diff options
author | Al Viro <viro@ftp.linux.org.uk> | 2007-12-22 12:42:36 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-12-22 22:53:06 -0500 |
commit | 51bf2976b55d07f9daae9697a0a3ac9f58abcedc (patch) | |
tree | b1db201fb4a4bd1103cccd64842e861f37e96361 /drivers/net/usb | |
parent | 7fd71e58b038a7244c2ac1ee579c43947f3968c4 (diff) |
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: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/usb')
-rw-r--r-- | drivers/net/usb/asix.c | 235 |
1 files changed, 105 insertions, 130 deletions
diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index 61daa096de66..1249f444039e 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c | |||
@@ -172,45 +172,76 @@ struct asix_data { | |||
172 | }; | 172 | }; |
173 | 173 | ||
174 | struct ax88172_int_data { | 174 | struct ax88172_int_data { |
175 | u16 res1; | 175 | __le16 res1; |
176 | u8 link; | 176 | u8 link; |
177 | u16 res2; | 177 | __le16 res2; |
178 | u8 status; | 178 | u8 status; |
179 | u16 res3; | 179 | __le16 res3; |
180 | } __attribute__ ((packed)); | 180 | } __attribute__ ((packed)); |
181 | 181 | ||
182 | static int asix_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, | 182 | static int asix_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, |
183 | u16 size, void *data) | 183 | u16 size, void *data) |
184 | { | 184 | { |
185 | void *buf; | ||
186 | int err = -ENOMEM; | ||
187 | |||
185 | devdbg(dev,"asix_read_cmd() cmd=0x%02x value=0x%04x index=0x%04x size=%d", | 188 | devdbg(dev,"asix_read_cmd() cmd=0x%02x value=0x%04x index=0x%04x size=%d", |
186 | cmd, value, index, size); | 189 | cmd, value, index, size); |
187 | return usb_control_msg( | 190 | |
191 | buf = kmalloc(size, GFP_KERNEL); | ||
192 | if (!buf) | ||
193 | goto out; | ||
194 | |||
195 | err = usb_control_msg( | ||
188 | dev->udev, | 196 | dev->udev, |
189 | usb_rcvctrlpipe(dev->udev, 0), | 197 | usb_rcvctrlpipe(dev->udev, 0), |
190 | cmd, | 198 | cmd, |
191 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 199 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
192 | value, | 200 | value, |
193 | index, | 201 | index, |
194 | data, | 202 | buf, |
195 | size, | 203 | size, |
196 | USB_CTRL_GET_TIMEOUT); | 204 | USB_CTRL_GET_TIMEOUT); |
205 | if (err >= 0 && err < size) | ||
206 | err = -EINVAL; | ||
207 | if (!err) | ||
208 | memcpy(data, buf, size); | ||
209 | kfree(buf); | ||
210 | |||
211 | out: | ||
212 | return err; | ||
197 | } | 213 | } |
198 | 214 | ||
199 | static int asix_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, | 215 | static int asix_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, |
200 | u16 size, void *data) | 216 | u16 size, void *data) |
201 | { | 217 | { |
218 | void *buf = NULL; | ||
219 | int err = -ENOMEM; | ||
220 | |||
202 | devdbg(dev,"asix_write_cmd() cmd=0x%02x value=0x%04x index=0x%04x size=%d", | 221 | devdbg(dev,"asix_write_cmd() cmd=0x%02x value=0x%04x index=0x%04x size=%d", |
203 | cmd, value, index, size); | 222 | cmd, value, index, size); |
204 | return usb_control_msg( | 223 | |
224 | if (data) { | ||
225 | buf = kmalloc(size, GFP_KERNEL); | ||
226 | if (!buf) | ||
227 | goto out; | ||
228 | memcpy(buf, data, size); | ||
229 | } | ||
230 | |||
231 | err = usb_control_msg( | ||
205 | dev->udev, | 232 | dev->udev, |
206 | usb_sndctrlpipe(dev->udev, 0), | 233 | usb_sndctrlpipe(dev->udev, 0), |
207 | cmd, | 234 | cmd, |
208 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 235 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
209 | value, | 236 | value, |
210 | index, | 237 | index, |
211 | data, | 238 | buf, |
212 | size, | 239 | size, |
213 | USB_CTRL_SET_TIMEOUT); | 240 | USB_CTRL_SET_TIMEOUT); |
241 | kfree(buf); | ||
242 | |||
243 | out: | ||
244 | return err; | ||
214 | } | 245 | } |
215 | 246 | ||
216 | static void asix_async_cmd_callback(struct urb *urb) | 247 | static void asix_async_cmd_callback(struct urb *urb) |
@@ -402,25 +433,19 @@ static inline int asix_set_hw_mii(struct usbnet *dev) | |||
402 | 433 | ||
403 | static inline int asix_get_phy_addr(struct usbnet *dev) | 434 | static inline int asix_get_phy_addr(struct usbnet *dev) |
404 | { | 435 | { |
405 | int ret = 0; | 436 | u8 buf[2]; |
406 | void *buf; | 437 | int ret = asix_read_cmd(dev, AX_CMD_READ_PHY_ID, 0, 0, 2, buf); |
407 | 438 | ||
408 | devdbg(dev, "asix_get_phy_addr()"); | 439 | devdbg(dev, "asix_get_phy_addr()"); |
409 | 440 | ||
410 | buf = kmalloc(2, GFP_KERNEL); | 441 | if (ret < 0) { |
411 | if (!buf) | ||
412 | goto out1; | ||
413 | |||
414 | if ((ret = asix_read_cmd(dev, AX_CMD_READ_PHY_ID, | ||
415 | 0, 0, 2, buf)) < 2) { | ||
416 | deverr(dev, "Error reading PHYID register: %02x", ret); | 442 | deverr(dev, "Error reading PHYID register: %02x", ret); |
417 | goto out2; | 443 | goto out; |
418 | } | 444 | } |
419 | devdbg(dev, "asix_get_phy_addr() returning 0x%04x", *((u16 *)buf)); | 445 | devdbg(dev, "asix_get_phy_addr() returning 0x%04x", *((__le16 *)buf)); |
420 | ret = *((u8 *)buf + 1); | 446 | ret = buf[1]; |
421 | out2: | 447 | |
422 | kfree(buf); | 448 | out: |
423 | out1: | ||
424 | return ret; | 449 | return ret; |
425 | } | 450 | } |
426 | 451 | ||
@@ -437,22 +462,15 @@ static int asix_sw_reset(struct usbnet *dev, u8 flags) | |||
437 | 462 | ||
438 | static u16 asix_read_rx_ctl(struct usbnet *dev) | 463 | static u16 asix_read_rx_ctl(struct usbnet *dev) |
439 | { | 464 | { |
440 | u16 ret = 0; | 465 | __le16 v; |
441 | void *buf; | 466 | int ret = asix_read_cmd(dev, AX_CMD_READ_RX_CTL, 0, 0, 2, &v); |
442 | |||
443 | buf = kmalloc(2, GFP_KERNEL); | ||
444 | if (!buf) | ||
445 | goto out1; | ||
446 | 467 | ||
447 | if ((ret = asix_read_cmd(dev, AX_CMD_READ_RX_CTL, | 468 | if (ret < 0) { |
448 | 0, 0, 2, buf)) < 2) { | ||
449 | deverr(dev, "Error reading RX_CTL register: %02x", ret); | 469 | deverr(dev, "Error reading RX_CTL register: %02x", ret); |
450 | goto out2; | 470 | goto out; |
451 | } | 471 | } |
452 | ret = le16_to_cpu(*((u16 *)buf)); | 472 | ret = le16_to_cpu(v); |
453 | out2: | 473 | out: |
454 | kfree(buf); | ||
455 | out1: | ||
456 | return ret; | 474 | return ret; |
457 | } | 475 | } |
458 | 476 | ||
@@ -471,22 +489,15 @@ static int asix_write_rx_ctl(struct usbnet *dev, u16 mode) | |||
471 | 489 | ||
472 | static u16 asix_read_medium_status(struct usbnet *dev) | 490 | static u16 asix_read_medium_status(struct usbnet *dev) |
473 | { | 491 | { |
474 | u16 ret = 0; | 492 | __le16 v; |
475 | void *buf; | 493 | int ret = asix_read_cmd(dev, AX_CMD_READ_MEDIUM_STATUS, 0, 0, 2, &v); |
476 | 494 | ||
477 | buf = kmalloc(2, GFP_KERNEL); | 495 | if (ret < 0) { |
478 | if (!buf) | ||
479 | goto out1; | ||
480 | |||
481 | if ((ret = asix_read_cmd(dev, AX_CMD_READ_MEDIUM_STATUS, | ||
482 | 0, 0, 2, buf)) < 2) { | ||
483 | deverr(dev, "Error reading Medium Status register: %02x", ret); | 496 | deverr(dev, "Error reading Medium Status register: %02x", ret); |
484 | goto out2; | 497 | goto out; |
485 | } | 498 | } |
486 | ret = le16_to_cpu(*((u16 *)buf)); | 499 | ret = le16_to_cpu(v); |
487 | out2: | 500 | out: |
488 | kfree(buf); | ||
489 | out1: | ||
490 | return ret; | 501 | return ret; |
491 | } | 502 | } |
492 | 503 | ||
@@ -568,31 +579,30 @@ static void asix_set_multicast(struct net_device *net) | |||
568 | static int asix_mdio_read(struct net_device *netdev, int phy_id, int loc) | 579 | static int asix_mdio_read(struct net_device *netdev, int phy_id, int loc) |
569 | { | 580 | { |
570 | struct usbnet *dev = netdev_priv(netdev); | 581 | struct usbnet *dev = netdev_priv(netdev); |
571 | u16 res; | 582 | __le16 res; |
572 | 583 | ||
573 | mutex_lock(&dev->phy_mutex); | 584 | mutex_lock(&dev->phy_mutex); |
574 | asix_set_sw_mii(dev); | 585 | asix_set_sw_mii(dev); |
575 | asix_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id, | 586 | asix_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id, |
576 | (__u16)loc, 2, (u16 *)&res); | 587 | (__u16)loc, 2, &res); |
577 | asix_set_hw_mii(dev); | 588 | asix_set_hw_mii(dev); |
578 | mutex_unlock(&dev->phy_mutex); | 589 | mutex_unlock(&dev->phy_mutex); |
579 | 590 | ||
580 | devdbg(dev, "asix_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x", phy_id, loc, le16_to_cpu(res & 0xffff)); | 591 | devdbg(dev, "asix_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x", phy_id, loc, le16_to_cpu(res)); |
581 | 592 | ||
582 | return le16_to_cpu(res & 0xffff); | 593 | return le16_to_cpu(res); |
583 | } | 594 | } |
584 | 595 | ||
585 | static void | 596 | static void |
586 | asix_mdio_write(struct net_device *netdev, int phy_id, int loc, int val) | 597 | asix_mdio_write(struct net_device *netdev, int phy_id, int loc, int val) |
587 | { | 598 | { |
588 | struct usbnet *dev = netdev_priv(netdev); | 599 | struct usbnet *dev = netdev_priv(netdev); |
589 | u16 res = cpu_to_le16(val); | 600 | __le16 res = cpu_to_le16(val); |
590 | 601 | ||
591 | devdbg(dev, "asix_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x", phy_id, loc, val); | 602 | devdbg(dev, "asix_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x", phy_id, loc, val); |
592 | mutex_lock(&dev->phy_mutex); | 603 | mutex_lock(&dev->phy_mutex); |
593 | asix_set_sw_mii(dev); | 604 | asix_set_sw_mii(dev); |
594 | asix_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, | 605 | asix_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, (__u16)loc, 2, &res); |
595 | (__u16)loc, 2, (u16 *)&res); | ||
596 | asix_set_hw_mii(dev); | 606 | asix_set_hw_mii(dev); |
597 | mutex_unlock(&dev->phy_mutex); | 607 | mutex_unlock(&dev->phy_mutex); |
598 | } | 608 | } |
@@ -644,7 +654,6 @@ asix_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) | |||
644 | { | 654 | { |
645 | struct usbnet *dev = netdev_priv(net); | 655 | struct usbnet *dev = netdev_priv(net); |
646 | u8 opt = 0; | 656 | u8 opt = 0; |
647 | u8 buf[1]; | ||
648 | 657 | ||
649 | if (wolinfo->wolopts & WAKE_PHY) | 658 | if (wolinfo->wolopts & WAKE_PHY) |
650 | opt |= AX_MONITOR_LINK; | 659 | opt |= AX_MONITOR_LINK; |
@@ -654,7 +663,7 @@ asix_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) | |||
654 | opt |= AX_MONITOR_MODE; | 663 | opt |= AX_MONITOR_MODE; |
655 | 664 | ||
656 | if (asix_write_cmd(dev, AX_CMD_WRITE_MONITOR_MODE, | 665 | if (asix_write_cmd(dev, AX_CMD_WRITE_MONITOR_MODE, |
657 | opt, 0, 0, &buf) < 0) | 666 | opt, 0, 0, NULL) < 0) |
658 | return -EINVAL; | 667 | return -EINVAL; |
659 | 668 | ||
660 | return 0; | 669 | return 0; |
@@ -672,7 +681,7 @@ static int asix_get_eeprom(struct net_device *net, | |||
672 | struct ethtool_eeprom *eeprom, u8 *data) | 681 | struct ethtool_eeprom *eeprom, u8 *data) |
673 | { | 682 | { |
674 | struct usbnet *dev = netdev_priv(net); | 683 | struct usbnet *dev = netdev_priv(net); |
675 | u16 *ebuf = (u16 *)data; | 684 | __le16 *ebuf = (__le16 *)data; |
676 | int i; | 685 | int i; |
677 | 686 | ||
678 | /* Crude hack to ensure that we don't overwrite memory | 687 | /* Crude hack to ensure that we don't overwrite memory |
@@ -801,7 +810,7 @@ static int ax88172_link_reset(struct usbnet *dev) | |||
801 | static int ax88172_bind(struct usbnet *dev, struct usb_interface *intf) | 810 | static int ax88172_bind(struct usbnet *dev, struct usb_interface *intf) |
802 | { | 811 | { |
803 | int ret = 0; | 812 | int ret = 0; |
804 | void *buf; | 813 | u8 buf[ETH_ALEN]; |
805 | int i; | 814 | int i; |
806 | unsigned long gpio_bits = dev->driver_info->data; | 815 | unsigned long gpio_bits = dev->driver_info->data; |
807 | struct asix_data *data = (struct asix_data *)&dev->data; | 816 | 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 | 819 | ||
811 | usbnet_get_endpoints(dev,intf); | 820 | usbnet_get_endpoints(dev,intf); |
812 | 821 | ||
813 | buf = kmalloc(ETH_ALEN, GFP_KERNEL); | ||
814 | if(!buf) { | ||
815 | ret = -ENOMEM; | ||
816 | goto out1; | ||
817 | } | ||
818 | |||
819 | /* Toggle the GPIOs in a manufacturer/model specific way */ | 822 | /* Toggle the GPIOs in a manufacturer/model specific way */ |
820 | for (i = 2; i >= 0; i--) { | 823 | for (i = 2; i >= 0; i--) { |
821 | if ((ret = asix_write_cmd(dev, AX_CMD_WRITE_GPIOS, | 824 | if ((ret = asix_write_cmd(dev, AX_CMD_WRITE_GPIOS, |
822 | (gpio_bits >> (i * 8)) & 0xff, 0, 0, | 825 | (gpio_bits >> (i * 8)) & 0xff, 0, 0, |
823 | buf)) < 0) | 826 | NULL)) < 0) |
824 | goto out2; | 827 | goto out; |
825 | msleep(5); | 828 | msleep(5); |
826 | } | 829 | } |
827 | 830 | ||
828 | if ((ret = asix_write_rx_ctl(dev, 0x80)) < 0) | 831 | if ((ret = asix_write_rx_ctl(dev, 0x80)) < 0) |
829 | goto out2; | 832 | goto out; |
830 | 833 | ||
831 | /* Get the MAC address */ | 834 | /* Get the MAC address */ |
832 | memset(buf, 0, ETH_ALEN); | ||
833 | if ((ret = asix_read_cmd(dev, AX88172_CMD_READ_NODE_ID, | 835 | if ((ret = asix_read_cmd(dev, AX88172_CMD_READ_NODE_ID, |
834 | 0, 0, 6, buf)) < 0) { | 836 | 0, 0, ETH_ALEN, buf)) < 0) { |
835 | dbg("read AX_CMD_READ_NODE_ID failed: %d", ret); | 837 | dbg("read AX_CMD_READ_NODE_ID failed: %d", ret); |
836 | goto out2; | 838 | goto out; |
837 | } | 839 | } |
838 | memcpy(dev->net->dev_addr, buf, ETH_ALEN); | 840 | memcpy(dev->net->dev_addr, buf, ETH_ALEN); |
839 | 841 | ||
@@ -855,9 +857,8 @@ static int ax88172_bind(struct usbnet *dev, struct usb_interface *intf) | |||
855 | mii_nway_restart(&dev->mii); | 857 | mii_nway_restart(&dev->mii); |
856 | 858 | ||
857 | return 0; | 859 | return 0; |
858 | out2: | 860 | |
859 | kfree(buf); | 861 | out: |
860 | out1: | ||
861 | return ret; | 862 | return ret; |
862 | } | 863 | } |
863 | 864 | ||
@@ -900,66 +901,58 @@ static int ax88772_link_reset(struct usbnet *dev) | |||
900 | static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) | 901 | static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) |
901 | { | 902 | { |
902 | int ret, embd_phy; | 903 | int ret, embd_phy; |
903 | void *buf; | ||
904 | u16 rx_ctl; | 904 | u16 rx_ctl; |
905 | struct asix_data *data = (struct asix_data *)&dev->data; | 905 | struct asix_data *data = (struct asix_data *)&dev->data; |
906 | u8 buf[ETH_ALEN]; | ||
906 | u32 phyid; | 907 | u32 phyid; |
907 | 908 | ||
908 | data->eeprom_len = AX88772_EEPROM_LEN; | 909 | data->eeprom_len = AX88772_EEPROM_LEN; |
909 | 910 | ||
910 | usbnet_get_endpoints(dev,intf); | 911 | usbnet_get_endpoints(dev,intf); |
911 | 912 | ||
912 | buf = kmalloc(6, GFP_KERNEL); | ||
913 | if(!buf) { | ||
914 | dbg ("Cannot allocate memory for buffer"); | ||
915 | ret = -ENOMEM; | ||
916 | goto out1; | ||
917 | } | ||
918 | |||
919 | if ((ret = asix_write_gpio(dev, | 913 | if ((ret = asix_write_gpio(dev, |
920 | AX_GPIO_RSE | AX_GPIO_GPO_2 | AX_GPIO_GPO2EN, 5)) < 0) | 914 | AX_GPIO_RSE | AX_GPIO_GPO_2 | AX_GPIO_GPO2EN, 5)) < 0) |
921 | goto out2; | 915 | goto out; |
922 | 916 | ||
923 | /* 0x10 is the phy id of the embedded 10/100 ethernet phy */ | 917 | /* 0x10 is the phy id of the embedded 10/100 ethernet phy */ |
924 | embd_phy = ((asix_get_phy_addr(dev) & 0x1f) == 0x10 ? 1 : 0); | 918 | embd_phy = ((asix_get_phy_addr(dev) & 0x1f) == 0x10 ? 1 : 0); |
925 | if ((ret = asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, | 919 | if ((ret = asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, |
926 | embd_phy, 0, 0, buf)) < 0) { | 920 | embd_phy, 0, 0, NULL)) < 0) { |
927 | dbg("Select PHY #1 failed: %d", ret); | 921 | dbg("Select PHY #1 failed: %d", ret); |
928 | goto out2; | 922 | goto out; |
929 | } | 923 | } |
930 | 924 | ||
931 | if ((ret = asix_sw_reset(dev, AX_SWRESET_IPPD | AX_SWRESET_PRL)) < 0) | 925 | if ((ret = asix_sw_reset(dev, AX_SWRESET_IPPD | AX_SWRESET_PRL)) < 0) |
932 | goto out2; | 926 | goto out; |
933 | 927 | ||
934 | msleep(150); | 928 | msleep(150); |
935 | if ((ret = asix_sw_reset(dev, AX_SWRESET_CLEAR)) < 0) | 929 | if ((ret = asix_sw_reset(dev, AX_SWRESET_CLEAR)) < 0) |
936 | goto out2; | 930 | goto out; |
937 | 931 | ||
938 | msleep(150); | 932 | msleep(150); |
939 | if (embd_phy) { | 933 | if (embd_phy) { |
940 | if ((ret = asix_sw_reset(dev, AX_SWRESET_IPRL)) < 0) | 934 | if ((ret = asix_sw_reset(dev, AX_SWRESET_IPRL)) < 0) |
941 | goto out2; | 935 | goto out; |
942 | } | 936 | } |
943 | else { | 937 | else { |
944 | if ((ret = asix_sw_reset(dev, AX_SWRESET_PRTE)) < 0) | 938 | if ((ret = asix_sw_reset(dev, AX_SWRESET_PRTE)) < 0) |
945 | goto out2; | 939 | goto out; |
946 | } | 940 | } |
947 | 941 | ||
948 | msleep(150); | 942 | msleep(150); |
949 | rx_ctl = asix_read_rx_ctl(dev); | 943 | rx_ctl = asix_read_rx_ctl(dev); |
950 | dbg("RX_CTL is 0x%04x after software reset", rx_ctl); | 944 | dbg("RX_CTL is 0x%04x after software reset", rx_ctl); |
951 | if ((ret = asix_write_rx_ctl(dev, 0x0000)) < 0) | 945 | if ((ret = asix_write_rx_ctl(dev, 0x0000)) < 0) |
952 | goto out2; | 946 | goto out; |
953 | 947 | ||
954 | rx_ctl = asix_read_rx_ctl(dev); | 948 | rx_ctl = asix_read_rx_ctl(dev); |
955 | dbg("RX_CTL is 0x%04x setting to 0x0000", rx_ctl); | 949 | dbg("RX_CTL is 0x%04x setting to 0x0000", rx_ctl); |
956 | 950 | ||
957 | /* Get the MAC address */ | 951 | /* Get the MAC address */ |
958 | memset(buf, 0, ETH_ALEN); | ||
959 | if ((ret = asix_read_cmd(dev, AX_CMD_READ_NODE_ID, | 952 | if ((ret = asix_read_cmd(dev, AX_CMD_READ_NODE_ID, |
960 | 0, 0, ETH_ALEN, buf)) < 0) { | 953 | 0, 0, ETH_ALEN, buf)) < 0) { |
961 | dbg("Failed to read MAC address: %d", ret); | 954 | dbg("Failed to read MAC address: %d", ret); |
962 | goto out2; | 955 | goto out; |
963 | } | 956 | } |
964 | memcpy(dev->net->dev_addr, buf, ETH_ALEN); | 957 | memcpy(dev->net->dev_addr, buf, ETH_ALEN); |
965 | 958 | ||
@@ -976,12 +969,12 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) | |||
976 | dbg("PHYID=0x%08x", phyid); | 969 | dbg("PHYID=0x%08x", phyid); |
977 | 970 | ||
978 | if ((ret = asix_sw_reset(dev, AX_SWRESET_PRL)) < 0) | 971 | if ((ret = asix_sw_reset(dev, AX_SWRESET_PRL)) < 0) |
979 | goto out2; | 972 | goto out; |
980 | 973 | ||
981 | msleep(150); | 974 | msleep(150); |
982 | 975 | ||
983 | if ((ret = asix_sw_reset(dev, AX_SWRESET_IPRL | AX_SWRESET_PRL)) < 0) | 976 | if ((ret = asix_sw_reset(dev, AX_SWRESET_IPRL | AX_SWRESET_PRL)) < 0) |
984 | goto out2; | 977 | goto out; |
985 | 978 | ||
986 | msleep(150); | 979 | msleep(150); |
987 | 980 | ||
@@ -994,18 +987,18 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) | |||
994 | mii_nway_restart(&dev->mii); | 987 | mii_nway_restart(&dev->mii); |
995 | 988 | ||
996 | if ((ret = asix_write_medium_mode(dev, AX88772_MEDIUM_DEFAULT)) < 0) | 989 | if ((ret = asix_write_medium_mode(dev, AX88772_MEDIUM_DEFAULT)) < 0) |
997 | goto out2; | 990 | goto out; |
998 | 991 | ||
999 | if ((ret = asix_write_cmd(dev, AX_CMD_WRITE_IPG0, | 992 | if ((ret = asix_write_cmd(dev, AX_CMD_WRITE_IPG0, |
1000 | AX88772_IPG0_DEFAULT | AX88772_IPG1_DEFAULT, | 993 | AX88772_IPG0_DEFAULT | AX88772_IPG1_DEFAULT, |
1001 | AX88772_IPG2_DEFAULT, 0, buf)) < 0) { | 994 | AX88772_IPG2_DEFAULT, 0, NULL)) < 0) { |
1002 | dbg("Write IPG,IPG1,IPG2 failed: %d", ret); | 995 | dbg("Write IPG,IPG1,IPG2 failed: %d", ret); |
1003 | goto out2; | 996 | goto out; |
1004 | } | 997 | } |
1005 | 998 | ||
1006 | /* Set RX_CTL to default values with 2k buffer, and enable cactus */ | 999 | /* Set RX_CTL to default values with 2k buffer, and enable cactus */ |
1007 | if ((ret = asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL)) < 0) | 1000 | if ((ret = asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL)) < 0) |
1008 | goto out2; | 1001 | goto out; |
1009 | 1002 | ||
1010 | rx_ctl = asix_read_rx_ctl(dev); | 1003 | rx_ctl = asix_read_rx_ctl(dev); |
1011 | dbg("RX_CTL is 0x%04x after all initializations", rx_ctl); | 1004 | 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 | rx_ctl = asix_read_medium_status(dev); | 1006 | rx_ctl = asix_read_medium_status(dev); |
1014 | dbg("Medium Status is 0x%04x after all initializations", rx_ctl); | 1007 | dbg("Medium Status is 0x%04x after all initializations", rx_ctl); |
1015 | 1008 | ||
1016 | kfree(buf); | ||
1017 | |||
1018 | /* Asix framing packs multiple eth frames into a 2K usb bulk transfer */ | 1009 | /* Asix framing packs multiple eth frames into a 2K usb bulk transfer */ |
1019 | if (dev->driver_info->flags & FLAG_FRAMING_AX) { | 1010 | if (dev->driver_info->flags & FLAG_FRAMING_AX) { |
1020 | /* hard_mtu is still the default - the device does not support | 1011 | /* hard_mtu is still the default - the device does not support |
1021 | jumbo eth frames */ | 1012 | jumbo eth frames */ |
1022 | dev->rx_urb_size = 2048; | 1013 | dev->rx_urb_size = 2048; |
1023 | } | 1014 | } |
1024 | |||
1025 | return 0; | 1015 | return 0; |
1026 | 1016 | ||
1027 | out2: | 1017 | out: |
1028 | kfree(buf); | ||
1029 | out1: | ||
1030 | return ret; | 1018 | return ret; |
1031 | } | 1019 | } |
1032 | 1020 | ||
@@ -1195,23 +1183,16 @@ static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf) | |||
1195 | { | 1183 | { |
1196 | struct asix_data *data = (struct asix_data *)&dev->data; | 1184 | struct asix_data *data = (struct asix_data *)&dev->data; |
1197 | int ret; | 1185 | int ret; |
1198 | void *buf; | 1186 | u8 buf[ETH_ALEN]; |
1199 | u16 eeprom; | 1187 | __le16 eeprom; |
1188 | u8 status; | ||
1200 | int gpio0 = 0; | 1189 | int gpio0 = 0; |
1201 | u32 phyid; | 1190 | u32 phyid; |
1202 | 1191 | ||
1203 | usbnet_get_endpoints(dev,intf); | 1192 | usbnet_get_endpoints(dev,intf); |
1204 | 1193 | ||
1205 | buf = kmalloc(6, GFP_KERNEL); | 1194 | asix_read_cmd(dev, AX_CMD_READ_GPIOS, 0, 0, 1, &status); |
1206 | if(!buf) { | 1195 | dbg("GPIO Status: 0x%04x", status); |
1207 | dbg ("Cannot allocate memory for buffer"); | ||
1208 | ret = -ENOMEM; | ||
1209 | goto out1; | ||
1210 | } | ||
1211 | |||
1212 | eeprom = 0; | ||
1213 | asix_read_cmd(dev, AX_CMD_READ_GPIOS, 0, 0, 1, &eeprom); | ||
1214 | dbg("GPIO Status: 0x%04x", eeprom); | ||
1215 | 1196 | ||
1216 | asix_write_cmd(dev, AX_CMD_WRITE_ENABLE, 0, 0, 0, NULL); | 1197 | asix_write_cmd(dev, AX_CMD_WRITE_ENABLE, 0, 0, 0, NULL); |
1217 | asix_read_cmd(dev, AX_CMD_READ_EEPROM, 0x0017, 0, 2, &eeprom); | 1198 | 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 | 1200 | ||
1220 | dbg("EEPROM index 0x17 is 0x%04x", eeprom); | 1201 | dbg("EEPROM index 0x17 is 0x%04x", eeprom); |
1221 | 1202 | ||
1222 | if (eeprom == 0xffff) { | 1203 | if (eeprom == cpu_to_le16(0xffff)) { |
1223 | data->phymode = PHY_MODE_MARVELL; | 1204 | data->phymode = PHY_MODE_MARVELL; |
1224 | data->ledmode = 0; | 1205 | data->ledmode = 0; |
1225 | gpio0 = 1; | 1206 | gpio0 = 1; |
1226 | } else { | 1207 | } else { |
1227 | data->phymode = eeprom & 7; | 1208 | data->phymode = le16_to_cpu(eeprom) & 7; |
1228 | data->ledmode = eeprom >> 8; | 1209 | data->ledmode = le16_to_cpu(eeprom) >> 8; |
1229 | gpio0 = (eeprom & 0x80) ? 0 : 1; | 1210 | gpio0 = (le16_to_cpu(eeprom) & 0x80) ? 0 : 1; |
1230 | } | 1211 | } |
1231 | dbg("GPIO0: %d, PhyMode: %d", gpio0, data->phymode); | 1212 | dbg("GPIO0: %d, PhyMode: %d", gpio0, data->phymode); |
1232 | 1213 | ||
1233 | asix_write_gpio(dev, AX_GPIO_RSE | AX_GPIO_GPO_1 | AX_GPIO_GPO1EN, 40); | 1214 | asix_write_gpio(dev, AX_GPIO_RSE | AX_GPIO_GPO_1 | AX_GPIO_GPO1EN, 40); |
1234 | if ((eeprom >> 8) != 1) { | 1215 | if ((le16_to_cpu(eeprom) >> 8) != 1) { |
1235 | asix_write_gpio(dev, 0x003c, 30); | 1216 | asix_write_gpio(dev, 0x003c, 30); |
1236 | asix_write_gpio(dev, 0x001c, 300); | 1217 | asix_write_gpio(dev, 0x001c, 300); |
1237 | asix_write_gpio(dev, 0x003c, 30); | 1218 | asix_write_gpio(dev, 0x003c, 30); |
@@ -1250,11 +1231,10 @@ static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf) | |||
1250 | asix_write_rx_ctl(dev, 0); | 1231 | asix_write_rx_ctl(dev, 0); |
1251 | 1232 | ||
1252 | /* Get the MAC address */ | 1233 | /* Get the MAC address */ |
1253 | memset(buf, 0, ETH_ALEN); | ||
1254 | if ((ret = asix_read_cmd(dev, AX_CMD_READ_NODE_ID, | 1234 | if ((ret = asix_read_cmd(dev, AX_CMD_READ_NODE_ID, |
1255 | 0, 0, ETH_ALEN, buf)) < 0) { | 1235 | 0, 0, ETH_ALEN, buf)) < 0) { |
1256 | dbg("Failed to read MAC address: %d", ret); | 1236 | dbg("Failed to read MAC address: %d", ret); |
1257 | goto out2; | 1237 | goto out; |
1258 | } | 1238 | } |
1259 | memcpy(dev->net->dev_addr, buf, ETH_ALEN); | 1239 | memcpy(dev->net->dev_addr, buf, ETH_ALEN); |
1260 | 1240 | ||
@@ -1289,12 +1269,10 @@ static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf) | |||
1289 | mii_nway_restart(&dev->mii); | 1269 | mii_nway_restart(&dev->mii); |
1290 | 1270 | ||
1291 | if ((ret = asix_write_medium_mode(dev, AX88178_MEDIUM_DEFAULT)) < 0) | 1271 | if ((ret = asix_write_medium_mode(dev, AX88178_MEDIUM_DEFAULT)) < 0) |
1292 | goto out2; | 1272 | goto out; |
1293 | 1273 | ||
1294 | if ((ret = asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL)) < 0) | 1274 | if ((ret = asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL)) < 0) |
1295 | goto out2; | 1275 | goto out; |
1296 | |||
1297 | kfree(buf); | ||
1298 | 1276 | ||
1299 | /* Asix framing packs multiple eth frames into a 2K usb bulk transfer */ | 1277 | /* Asix framing packs multiple eth frames into a 2K usb bulk transfer */ |
1300 | if (dev->driver_info->flags & FLAG_FRAMING_AX) { | 1278 | if (dev->driver_info->flags & FLAG_FRAMING_AX) { |
@@ -1302,12 +1280,9 @@ static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf) | |||
1302 | jumbo eth frames */ | 1280 | jumbo eth frames */ |
1303 | dev->rx_urb_size = 2048; | 1281 | dev->rx_urb_size = 2048; |
1304 | } | 1282 | } |
1305 | |||
1306 | return 0; | 1283 | return 0; |
1307 | 1284 | ||
1308 | out2: | 1285 | out: |
1309 | kfree(buf); | ||
1310 | out1: | ||
1311 | return ret; | 1286 | return ret; |
1312 | } | 1287 | } |
1313 | 1288 | ||