Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at 77b2555b52a894a2e39a42e43d993df875c46a6a 948 lines 25 kB view raw
1/* 2 * ASIX AX8817X based USB 2.0 Ethernet Devices 3 * Copyright (C) 2003-2005 David Hollis <dhollis@davehollis.com> 4 * Copyright (C) 2005 Phil Chang <pchang23@sbcglobal.net> 5 * Copyright (c) 2002-2003 TiVo Inc. 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 */ 21 22// #define DEBUG // error path messages, extra info 23// #define VERBOSE // more; success messages 24 25#include <linux/config.h> 26#ifdef CONFIG_USB_DEBUG 27# define DEBUG 28#endif 29#include <linux/module.h> 30#include <linux/kmod.h> 31#include <linux/sched.h> 32#include <linux/init.h> 33#include <linux/netdevice.h> 34#include <linux/etherdevice.h> 35#include <linux/ethtool.h> 36#include <linux/workqueue.h> 37#include <linux/mii.h> 38#include <linux/usb.h> 39#include <linux/crc32.h> 40 41#include "usbnet.h" 42 43 44/* ASIX AX8817X based USB 2.0 Ethernet Devices */ 45 46#define AX_CMD_SET_SW_MII 0x06 47#define AX_CMD_READ_MII_REG 0x07 48#define AX_CMD_WRITE_MII_REG 0x08 49#define AX_CMD_SET_HW_MII 0x0a 50#define AX_CMD_READ_EEPROM 0x0b 51#define AX_CMD_WRITE_EEPROM 0x0c 52#define AX_CMD_WRITE_ENABLE 0x0d 53#define AX_CMD_WRITE_DISABLE 0x0e 54#define AX_CMD_WRITE_RX_CTL 0x10 55#define AX_CMD_READ_IPG012 0x11 56#define AX_CMD_WRITE_IPG0 0x12 57#define AX_CMD_WRITE_IPG1 0x13 58#define AX_CMD_WRITE_IPG2 0x14 59#define AX_CMD_WRITE_MULTI_FILTER 0x16 60#define AX_CMD_READ_NODE_ID 0x17 61#define AX_CMD_READ_PHY_ID 0x19 62#define AX_CMD_READ_MEDIUM_STATUS 0x1a 63#define AX_CMD_WRITE_MEDIUM_MODE 0x1b 64#define AX_CMD_READ_MONITOR_MODE 0x1c 65#define AX_CMD_WRITE_MONITOR_MODE 0x1d 66#define AX_CMD_WRITE_GPIOS 0x1f 67#define AX_CMD_SW_RESET 0x20 68#define AX_CMD_SW_PHY_STATUS 0x21 69#define AX_CMD_SW_PHY_SELECT 0x22 70#define AX88772_CMD_READ_NODE_ID 0x13 71 72#define AX_MONITOR_MODE 0x01 73#define AX_MONITOR_LINK 0x02 74#define AX_MONITOR_MAGIC 0x04 75#define AX_MONITOR_HSFS 0x10 76 77/* AX88172 Medium Status Register values */ 78#define AX_MEDIUM_FULL_DUPLEX 0x02 79#define AX_MEDIUM_TX_ABORT_ALLOW 0x04 80#define AX_MEDIUM_FLOW_CONTROL_EN 0x10 81 82#define AX_MCAST_FILTER_SIZE 8 83#define AX_MAX_MCAST 64 84 85#define AX_EEPROM_LEN 0x40 86 87#define AX_SWRESET_CLEAR 0x00 88#define AX_SWRESET_RR 0x01 89#define AX_SWRESET_RT 0x02 90#define AX_SWRESET_PRTE 0x04 91#define AX_SWRESET_PRL 0x08 92#define AX_SWRESET_BZ 0x10 93#define AX_SWRESET_IPRL 0x20 94#define AX_SWRESET_IPPD 0x40 95 96#define AX88772_IPG0_DEFAULT 0x15 97#define AX88772_IPG1_DEFAULT 0x0c 98#define AX88772_IPG2_DEFAULT 0x12 99 100#define AX88772_MEDIUM_FULL_DUPLEX 0x0002 101#define AX88772_MEDIUM_RESERVED 0x0004 102#define AX88772_MEDIUM_RX_FC_ENABLE 0x0010 103#define AX88772_MEDIUM_TX_FC_ENABLE 0x0020 104#define AX88772_MEDIUM_PAUSE_FORMAT 0x0080 105#define AX88772_MEDIUM_RX_ENABLE 0x0100 106#define AX88772_MEDIUM_100MB 0x0200 107#define AX88772_MEDIUM_DEFAULT \ 108 (AX88772_MEDIUM_FULL_DUPLEX | AX88772_MEDIUM_RX_FC_ENABLE | \ 109 AX88772_MEDIUM_TX_FC_ENABLE | AX88772_MEDIUM_100MB | \ 110 AX88772_MEDIUM_RESERVED | AX88772_MEDIUM_RX_ENABLE ) 111 112#define AX_EEPROM_MAGIC 0xdeadbeef 113 114/* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */ 115struct ax8817x_data { 116 u8 multi_filter[AX_MCAST_FILTER_SIZE]; 117}; 118 119struct ax88172_int_data { 120 u16 res1; 121 u8 link; 122 u16 res2; 123 u8 status; 124 u16 res3; 125} __attribute__ ((packed)); 126 127static int ax8817x_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, 128 u16 size, void *data) 129{ 130 return usb_control_msg( 131 dev->udev, 132 usb_rcvctrlpipe(dev->udev, 0), 133 cmd, 134 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 135 value, 136 index, 137 data, 138 size, 139 USB_CTRL_GET_TIMEOUT); 140} 141 142static int ax8817x_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, 143 u16 size, void *data) 144{ 145 return usb_control_msg( 146 dev->udev, 147 usb_sndctrlpipe(dev->udev, 0), 148 cmd, 149 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 150 value, 151 index, 152 data, 153 size, 154 USB_CTRL_SET_TIMEOUT); 155} 156 157static void ax8817x_async_cmd_callback(struct urb *urb, struct pt_regs *regs) 158{ 159 struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context; 160 161 if (urb->status < 0) 162 printk(KERN_DEBUG "ax8817x_async_cmd_callback() failed with %d", 163 urb->status); 164 165 kfree(req); 166 usb_free_urb(urb); 167} 168 169static void ax8817x_status(struct usbnet *dev, struct urb *urb) 170{ 171 struct ax88172_int_data *event; 172 int link; 173 174 if (urb->actual_length < 8) 175 return; 176 177 event = urb->transfer_buffer; 178 link = event->link & 0x01; 179 if (netif_carrier_ok(dev->net) != link) { 180 if (link) { 181 netif_carrier_on(dev->net); 182 usbnet_defer_kevent (dev, EVENT_LINK_RESET ); 183 } else 184 netif_carrier_off(dev->net); 185 devdbg(dev, "ax8817x - Link Status is: %d", link); 186 } 187} 188 189static void 190ax8817x_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index, 191 u16 size, void *data) 192{ 193 struct usb_ctrlrequest *req; 194 int status; 195 struct urb *urb; 196 197 if ((urb = usb_alloc_urb(0, GFP_ATOMIC)) == NULL) { 198 devdbg(dev, "Error allocating URB in write_cmd_async!"); 199 return; 200 } 201 202 if ((req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC)) == NULL) { 203 deverr(dev, "Failed to allocate memory for control request"); 204 usb_free_urb(urb); 205 return; 206 } 207 208 req->bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE; 209 req->bRequest = cmd; 210 req->wValue = cpu_to_le16(value); 211 req->wIndex = cpu_to_le16(index); 212 req->wLength = cpu_to_le16(size); 213 214 usb_fill_control_urb(urb, dev->udev, 215 usb_sndctrlpipe(dev->udev, 0), 216 (void *)req, data, size, 217 ax8817x_async_cmd_callback, req); 218 219 if((status = usb_submit_urb(urb, GFP_ATOMIC)) < 0) { 220 deverr(dev, "Error submitting the control message: status=%d", 221 status); 222 kfree(req); 223 usb_free_urb(urb); 224 } 225} 226 227static void ax8817x_set_multicast(struct net_device *net) 228{ 229 struct usbnet *dev = netdev_priv(net); 230 struct ax8817x_data *data = (struct ax8817x_data *)&dev->data; 231 u8 rx_ctl = 0x8c; 232 233 if (net->flags & IFF_PROMISC) { 234 rx_ctl |= 0x01; 235 } else if (net->flags & IFF_ALLMULTI 236 || net->mc_count > AX_MAX_MCAST) { 237 rx_ctl |= 0x02; 238 } else if (net->mc_count == 0) { 239 /* just broadcast and directed */ 240 } else { 241 /* We use the 20 byte dev->data 242 * for our 8 byte filter buffer 243 * to avoid allocating memory that 244 * is tricky to free later */ 245 struct dev_mc_list *mc_list = net->mc_list; 246 u32 crc_bits; 247 int i; 248 249 memset(data->multi_filter, 0, AX_MCAST_FILTER_SIZE); 250 251 /* Build the multicast hash filter. */ 252 for (i = 0; i < net->mc_count; i++) { 253 crc_bits = 254 ether_crc(ETH_ALEN, 255 mc_list->dmi_addr) >> 26; 256 data->multi_filter[crc_bits >> 3] |= 257 1 << (crc_bits & 7); 258 mc_list = mc_list->next; 259 } 260 261 ax8817x_write_cmd_async(dev, AX_CMD_WRITE_MULTI_FILTER, 0, 0, 262 AX_MCAST_FILTER_SIZE, data->multi_filter); 263 264 rx_ctl |= 0x10; 265 } 266 267 ax8817x_write_cmd_async(dev, AX_CMD_WRITE_RX_CTL, rx_ctl, 0, 0, NULL); 268} 269 270static int ax8817x_mdio_read(struct net_device *netdev, int phy_id, int loc) 271{ 272 struct usbnet *dev = netdev_priv(netdev); 273 u16 res; 274 u8 buf[1]; 275 276 ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII, 0, 0, 0, &buf); 277 ax8817x_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id, 278 (__u16)loc, 2, (u16 *)&res); 279 ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, &buf); 280 281 return res & 0xffff; 282} 283 284/* same as above, but converts resulting value to cpu byte order */ 285static int ax8817x_mdio_read_le(struct net_device *netdev, int phy_id, int loc) 286{ 287 return le16_to_cpu(ax8817x_mdio_read(netdev,phy_id, loc)); 288} 289 290static void 291ax8817x_mdio_write(struct net_device *netdev, int phy_id, int loc, int val) 292{ 293 struct usbnet *dev = netdev_priv(netdev); 294 u16 res = val; 295 u8 buf[1]; 296 297 ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII, 0, 0, 0, &buf); 298 ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, 299 (__u16)loc, 2, (u16 *)&res); 300 ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, &buf); 301} 302 303/* same as above, but converts new value to le16 byte order before writing */ 304static void 305ax8817x_mdio_write_le(struct net_device *netdev, int phy_id, int loc, int val) 306{ 307 ax8817x_mdio_write( netdev, phy_id, loc, cpu_to_le16(val) ); 308} 309 310static int ax88172_link_reset(struct usbnet *dev) 311{ 312 u16 lpa; 313 u16 adv; 314 u16 res; 315 u8 mode; 316 317 mode = AX_MEDIUM_TX_ABORT_ALLOW | AX_MEDIUM_FLOW_CONTROL_EN; 318 lpa = ax8817x_mdio_read_le(dev->net, dev->mii.phy_id, MII_LPA); 319 adv = ax8817x_mdio_read_le(dev->net, dev->mii.phy_id, MII_ADVERTISE); 320 res = mii_nway_result(lpa|adv); 321 if (res & LPA_DUPLEX) 322 mode |= AX_MEDIUM_FULL_DUPLEX; 323 ax8817x_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL); 324 325 return 0; 326} 327 328static void 329ax8817x_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) 330{ 331 struct usbnet *dev = netdev_priv(net); 332 u8 opt; 333 334 if (ax8817x_read_cmd(dev, AX_CMD_READ_MONITOR_MODE, 0, 0, 1, &opt) < 0) { 335 wolinfo->supported = 0; 336 wolinfo->wolopts = 0; 337 return; 338 } 339 wolinfo->supported = WAKE_PHY | WAKE_MAGIC; 340 wolinfo->wolopts = 0; 341 if (opt & AX_MONITOR_MODE) { 342 if (opt & AX_MONITOR_LINK) 343 wolinfo->wolopts |= WAKE_PHY; 344 if (opt & AX_MONITOR_MAGIC) 345 wolinfo->wolopts |= WAKE_MAGIC; 346 } 347} 348 349static int 350ax8817x_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) 351{ 352 struct usbnet *dev = netdev_priv(net); 353 u8 opt = 0; 354 u8 buf[1]; 355 356 if (wolinfo->wolopts & WAKE_PHY) 357 opt |= AX_MONITOR_LINK; 358 if (wolinfo->wolopts & WAKE_MAGIC) 359 opt |= AX_MONITOR_MAGIC; 360 if (opt != 0) 361 opt |= AX_MONITOR_MODE; 362 363 if (ax8817x_write_cmd(dev, AX_CMD_WRITE_MONITOR_MODE, 364 opt, 0, 0, &buf) < 0) 365 return -EINVAL; 366 367 return 0; 368} 369 370static int ax8817x_get_eeprom_len(struct net_device *net) 371{ 372 return AX_EEPROM_LEN; 373} 374 375static int ax8817x_get_eeprom(struct net_device *net, 376 struct ethtool_eeprom *eeprom, u8 *data) 377{ 378 struct usbnet *dev = netdev_priv(net); 379 u16 *ebuf = (u16 *)data; 380 int i; 381 382 /* Crude hack to ensure that we don't overwrite memory 383 * if an odd length is supplied 384 */ 385 if (eeprom->len % 2) 386 return -EINVAL; 387 388 eeprom->magic = AX_EEPROM_MAGIC; 389 390 /* ax8817x returns 2 bytes from eeprom on read */ 391 for (i=0; i < eeprom->len / 2; i++) { 392 if (ax8817x_read_cmd(dev, AX_CMD_READ_EEPROM, 393 eeprom->offset + i, 0, 2, &ebuf[i]) < 0) 394 return -EINVAL; 395 } 396 return 0; 397} 398 399static void ax8817x_get_drvinfo (struct net_device *net, 400 struct ethtool_drvinfo *info) 401{ 402 /* Inherit standard device info */ 403 usbnet_get_drvinfo(net, info); 404 info->eedump_len = 0x3e; 405} 406 407static int ax8817x_get_settings(struct net_device *net, struct ethtool_cmd *cmd) 408{ 409 struct usbnet *dev = netdev_priv(net); 410 411 return mii_ethtool_gset(&dev->mii,cmd); 412} 413 414static int ax8817x_set_settings(struct net_device *net, struct ethtool_cmd *cmd) 415{ 416 struct usbnet *dev = netdev_priv(net); 417 418 return mii_ethtool_sset(&dev->mii,cmd); 419} 420 421/* We need to override some ethtool_ops so we require our 422 own structure so we don't interfere with other usbnet 423 devices that may be connected at the same time. */ 424static struct ethtool_ops ax8817x_ethtool_ops = { 425 .get_drvinfo = ax8817x_get_drvinfo, 426 .get_link = ethtool_op_get_link, 427 .get_msglevel = usbnet_get_msglevel, 428 .set_msglevel = usbnet_set_msglevel, 429 .get_wol = ax8817x_get_wol, 430 .set_wol = ax8817x_set_wol, 431 .get_eeprom_len = ax8817x_get_eeprom_len, 432 .get_eeprom = ax8817x_get_eeprom, 433 .get_settings = ax8817x_get_settings, 434 .set_settings = ax8817x_set_settings, 435}; 436 437static int ax8817x_ioctl (struct net_device *net, struct ifreq *rq, int cmd) 438{ 439 struct usbnet *dev = netdev_priv(net); 440 441 return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); 442} 443 444static int ax8817x_bind(struct usbnet *dev, struct usb_interface *intf) 445{ 446 int ret = 0; 447 void *buf; 448 int i; 449 unsigned long gpio_bits = dev->driver_info->data; 450 451 usbnet_get_endpoints(dev,intf); 452 453 buf = kmalloc(ETH_ALEN, GFP_KERNEL); 454 if(!buf) { 455 ret = -ENOMEM; 456 goto out1; 457 } 458 459 /* Toggle the GPIOs in a manufacturer/model specific way */ 460 for (i = 2; i >= 0; i--) { 461 if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_GPIOS, 462 (gpio_bits >> (i * 8)) & 0xff, 0, 0, 463 buf)) < 0) 464 goto out2; 465 msleep(5); 466 } 467 468 if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_RX_CTL, 469 0x80, 0, 0, buf)) < 0) { 470 dbg("send AX_CMD_WRITE_RX_CTL failed: %d", ret); 471 goto out2; 472 } 473 474 /* Get the MAC address */ 475 memset(buf, 0, ETH_ALEN); 476 if ((ret = ax8817x_read_cmd(dev, AX_CMD_READ_NODE_ID, 477 0, 0, 6, buf)) < 0) { 478 dbg("read AX_CMD_READ_NODE_ID failed: %d", ret); 479 goto out2; 480 } 481 memcpy(dev->net->dev_addr, buf, ETH_ALEN); 482 483 /* Get the PHY id */ 484 if ((ret = ax8817x_read_cmd(dev, AX_CMD_READ_PHY_ID, 485 0, 0, 2, buf)) < 0) { 486 dbg("error on read AX_CMD_READ_PHY_ID: %02x", ret); 487 goto out2; 488 } else if (ret < 2) { 489 /* this should always return 2 bytes */ 490 dbg("AX_CMD_READ_PHY_ID returned less than 2 bytes: ret=%02x", 491 ret); 492 ret = -EIO; 493 goto out2; 494 } 495 496 /* Initialize MII structure */ 497 dev->mii.dev = dev->net; 498 dev->mii.mdio_read = ax8817x_mdio_read; 499 dev->mii.mdio_write = ax8817x_mdio_write; 500 dev->mii.phy_id_mask = 0x3f; 501 dev->mii.reg_num_mask = 0x1f; 502 dev->mii.phy_id = *((u8 *)buf + 1); 503 dev->net->do_ioctl = ax8817x_ioctl; 504 505 dev->net->set_multicast_list = ax8817x_set_multicast; 506 dev->net->ethtool_ops = &ax8817x_ethtool_ops; 507 508 ax8817x_mdio_write_le(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET); 509 ax8817x_mdio_write_le(dev->net, dev->mii.phy_id, MII_ADVERTISE, 510 ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP); 511 mii_nway_restart(&dev->mii); 512 513 return 0; 514out2: 515 kfree(buf); 516out1: 517 return ret; 518} 519 520static struct ethtool_ops ax88772_ethtool_ops = { 521 .get_drvinfo = ax8817x_get_drvinfo, 522 .get_link = ethtool_op_get_link, 523 .get_msglevel = usbnet_get_msglevel, 524 .set_msglevel = usbnet_set_msglevel, 525 .get_wol = ax8817x_get_wol, 526 .set_wol = ax8817x_set_wol, 527 .get_eeprom_len = ax8817x_get_eeprom_len, 528 .get_eeprom = ax8817x_get_eeprom, 529 .get_settings = ax8817x_get_settings, 530 .set_settings = ax8817x_set_settings, 531}; 532 533static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) 534{ 535 int ret; 536 void *buf; 537 538 usbnet_get_endpoints(dev,intf); 539 540 buf = kmalloc(6, GFP_KERNEL); 541 if(!buf) { 542 dbg ("Cannot allocate memory for buffer"); 543 ret = -ENOMEM; 544 goto out1; 545 } 546 547 if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_GPIOS, 548 0x00B0, 0, 0, buf)) < 0) 549 goto out2; 550 551 msleep(5); 552 if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_PHY_SELECT, 553 0x0001, 0, 0, buf)) < 0) { 554 dbg("Select PHY #1 failed: %d", ret); 555 goto out2; 556 } 557 558 if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_IPPD, 559 0, 0, buf)) < 0) { 560 dbg("Failed to power down internal PHY: %d", ret); 561 goto out2; 562 } 563 564 msleep(150); 565 if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_CLEAR, 566 0, 0, buf)) < 0) { 567 dbg("Failed to perform software reset: %d", ret); 568 goto out2; 569 } 570 571 msleep(150); 572 if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_RESET, 573 AX_SWRESET_IPRL | AX_SWRESET_PRL, 574 0, 0, buf)) < 0) { 575 dbg("Failed to set Internal/External PHY reset control: %d", 576 ret); 577 goto out2; 578 } 579 580 msleep(150); 581 if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_RX_CTL, 582 0x0000, 0, 0, buf)) < 0) { 583 dbg("Failed to reset RX_CTL: %d", ret); 584 goto out2; 585 } 586 587 /* Get the MAC address */ 588 memset(buf, 0, ETH_ALEN); 589 if ((ret = ax8817x_read_cmd(dev, AX88772_CMD_READ_NODE_ID, 590 0, 0, ETH_ALEN, buf)) < 0) { 591 dbg("Failed to read MAC address: %d", ret); 592 goto out2; 593 } 594 memcpy(dev->net->dev_addr, buf, ETH_ALEN); 595 596 if ((ret = ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII, 597 0, 0, 0, buf)) < 0) { 598 dbg("Enabling software MII failed: %d", ret); 599 goto out2; 600 } 601 602 if (((ret = ax8817x_read_cmd(dev, AX_CMD_READ_MII_REG, 603 0x0010, 2, 2, buf)) < 0) 604 || (*((u16 *)buf) != 0x003b)) { 605 dbg("Read PHY register 2 must be 0x3b00: %d", ret); 606 goto out2; 607 } 608 609 /* Initialize MII structure */ 610 dev->mii.dev = dev->net; 611 dev->mii.mdio_read = ax8817x_mdio_read; 612 dev->mii.mdio_write = ax8817x_mdio_write; 613 dev->mii.phy_id_mask = 0xff; 614 dev->mii.reg_num_mask = 0xff; 615 dev->net->do_ioctl = ax8817x_ioctl; 616 617 /* Get the PHY id */ 618 if ((ret = ax8817x_read_cmd(dev, AX_CMD_READ_PHY_ID, 619 0, 0, 2, buf)) < 0) { 620 dbg("Error reading PHY ID: %02x", ret); 621 goto out2; 622 } else if (ret < 2) { 623 /* this should always return 2 bytes */ 624 dbg("AX_CMD_READ_PHY_ID returned less than 2 bytes: ret=%02x", 625 ret); 626 ret = -EIO; 627 goto out2; 628 } 629 dev->mii.phy_id = *((u8 *)buf + 1); 630 631 if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_RESET, AX_SWRESET_PRL, 632 0, 0, buf)) < 0) { 633 dbg("Set external PHY reset pin level: %d", ret); 634 goto out2; 635 } 636 msleep(150); 637 if ((ret = ax8817x_write_cmd(dev, AX_CMD_SW_RESET, 638 AX_SWRESET_IPRL | AX_SWRESET_PRL, 639 0, 0, buf)) < 0) { 640 dbg("Set Internal/External PHY reset control: %d", ret); 641 goto out2; 642 } 643 msleep(150); 644 645 646 dev->net->set_multicast_list = ax8817x_set_multicast; 647 dev->net->ethtool_ops = &ax88772_ethtool_ops; 648 649 ax8817x_mdio_write_le(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET); 650 ax8817x_mdio_write_le(dev->net, dev->mii.phy_id, MII_ADVERTISE, 651 ADVERTISE_ALL | ADVERTISE_CSMA); 652 mii_nway_restart(&dev->mii); 653 654 if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, 655 AX88772_MEDIUM_DEFAULT, 0, 0, buf)) < 0) { 656 dbg("Write medium mode register: %d", ret); 657 goto out2; 658 } 659 660 if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_IPG0, 661 AX88772_IPG0_DEFAULT | AX88772_IPG1_DEFAULT, 662 AX88772_IPG2_DEFAULT, 0, buf)) < 0) { 663 dbg("Write IPG,IPG1,IPG2 failed: %d", ret); 664 goto out2; 665 } 666 if ((ret = 667 ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, &buf)) < 0) { 668 dbg("Failed to set hardware MII: %02x", ret); 669 goto out2; 670 } 671 672 /* Set RX_CTL to default values with 2k buffer, and enable cactus */ 673 if ((ret = 674 ax8817x_write_cmd(dev, AX_CMD_WRITE_RX_CTL, 0x0088, 0, 0, 675 buf)) < 0) { 676 dbg("Reset RX_CTL failed: %d", ret); 677 goto out2; 678 } 679 680 kfree(buf); 681 682 /* Asix framing packs multiple eth frames into a 2K usb bulk transfer */ 683 if (dev->driver_info->flags & FLAG_FRAMING_AX) { 684 /* hard_mtu is still the default - the device does not support 685 jumbo eth frames */ 686 dev->rx_urb_size = 2048; 687 } 688 689 return 0; 690 691out2: 692 kfree(buf); 693out1: 694 return ret; 695} 696 697static int ax88772_rx_fixup(struct usbnet *dev, struct sk_buff *skb) 698{ 699 u8 *head; 700 u32 header; 701 char *packet; 702 struct sk_buff *ax_skb; 703 u16 size; 704 705 head = (u8 *) skb->data; 706 memcpy(&header, head, sizeof(header)); 707 le32_to_cpus(&header); 708 packet = head + sizeof(header); 709 710 skb_pull(skb, 4); 711 712 while (skb->len > 0) { 713 if ((short)(header & 0x0000ffff) != 714 ~((short)((header & 0xffff0000) >> 16))) { 715 devdbg(dev,"header length data is error"); 716 } 717 /* get the packet length */ 718 size = (u16) (header & 0x0000ffff); 719 720 if ((skb->len) - ((size + 1) & 0xfffe) == 0) 721 return 2; 722 if (size > ETH_FRAME_LEN) { 723 devdbg(dev,"invalid rx length %d", size); 724 return 0; 725 } 726 ax_skb = skb_clone(skb, GFP_ATOMIC); 727 if (ax_skb) { 728 ax_skb->len = size; 729 ax_skb->data = packet; 730 ax_skb->tail = packet + size; 731 usbnet_skb_return(dev, ax_skb); 732 } else { 733 return 0; 734 } 735 736 skb_pull(skb, (size + 1) & 0xfffe); 737 738 if (skb->len == 0) 739 break; 740 741 head = (u8 *) skb->data; 742 memcpy(&header, head, sizeof(header)); 743 le32_to_cpus(&header); 744 packet = head + sizeof(header); 745 skb_pull(skb, 4); 746 } 747 748 if (skb->len < 0) { 749 devdbg(dev,"invalid rx length %d", skb->len); 750 return 0; 751 } 752 return 1; 753} 754 755static struct sk_buff *ax88772_tx_fixup(struct usbnet *dev, struct sk_buff *skb, 756 unsigned flags) 757{ 758 int padlen; 759 int headroom = skb_headroom(skb); 760 int tailroom = skb_tailroom(skb); 761 u32 packet_len; 762 u32 padbytes = 0xffff0000; 763 764 padlen = ((skb->len + 4) % 512) ? 0 : 4; 765 766 if ((!skb_cloned(skb)) 767 && ((headroom + tailroom) >= (4 + padlen))) { 768 if ((headroom < 4) || (tailroom < padlen)) { 769 skb->data = memmove(skb->head + 4, skb->data, skb->len); 770 skb->tail = skb->data + skb->len; 771 } 772 } else { 773 struct sk_buff *skb2; 774 skb2 = skb_copy_expand(skb, 4, padlen, flags); 775 dev_kfree_skb_any(skb); 776 skb = skb2; 777 if (!skb) 778 return NULL; 779 } 780 781 skb_push(skb, 4); 782 packet_len = (((skb->len - 4) ^ 0x0000ffff) << 16) + (skb->len - 4); 783 memcpy(skb->data, &packet_len, sizeof(packet_len)); 784 785 if ((skb->len % 512) == 0) { 786 memcpy( skb->tail, &padbytes, sizeof(padbytes)); 787 skb_put(skb, sizeof(padbytes)); 788 } 789 return skb; 790} 791 792static int ax88772_link_reset(struct usbnet *dev) 793{ 794 u16 lpa; 795 u16 adv; 796 u16 res; 797 u16 mode; 798 799 mode = AX88772_MEDIUM_DEFAULT; 800 lpa = ax8817x_mdio_read_le(dev->net, dev->mii.phy_id, MII_LPA); 801 adv = ax8817x_mdio_read_le(dev->net, dev->mii.phy_id, MII_ADVERTISE); 802 res = mii_nway_result(lpa|adv); 803 804 if ((res & LPA_DUPLEX) == 0) 805 mode &= ~AX88772_MEDIUM_FULL_DUPLEX; 806 if ((res & LPA_100) == 0) 807 mode &= ~AX88772_MEDIUM_100MB; 808 ax8817x_write_cmd(dev, AX_CMD_WRITE_MEDIUM_MODE, mode, 0, 0, NULL); 809 810 return 0; 811} 812 813static const struct driver_info ax8817x_info = { 814 .description = "ASIX AX8817x USB 2.0 Ethernet", 815 .bind = ax8817x_bind, 816 .status = ax8817x_status, 817 .link_reset = ax88172_link_reset, 818 .reset = ax88172_link_reset, 819 .flags = FLAG_ETHER, 820 .data = 0x00130103, 821}; 822 823static const struct driver_info dlink_dub_e100_info = { 824 .description = "DLink DUB-E100 USB Ethernet", 825 .bind = ax8817x_bind, 826 .status = ax8817x_status, 827 .link_reset = ax88172_link_reset, 828 .reset = ax88172_link_reset, 829 .flags = FLAG_ETHER, 830 .data = 0x009f9d9f, 831}; 832 833static const struct driver_info netgear_fa120_info = { 834 .description = "Netgear FA-120 USB Ethernet", 835 .bind = ax8817x_bind, 836 .status = ax8817x_status, 837 .link_reset = ax88172_link_reset, 838 .reset = ax88172_link_reset, 839 .flags = FLAG_ETHER, 840 .data = 0x00130103, 841}; 842 843static const struct driver_info hawking_uf200_info = { 844 .description = "Hawking UF200 USB Ethernet", 845 .bind = ax8817x_bind, 846 .status = ax8817x_status, 847 .link_reset = ax88172_link_reset, 848 .reset = ax88172_link_reset, 849 .flags = FLAG_ETHER, 850 .data = 0x001f1d1f, 851}; 852 853static const struct driver_info ax88772_info = { 854 .description = "ASIX AX88772 USB 2.0 Ethernet", 855 .bind = ax88772_bind, 856 .status = ax8817x_status, 857 .link_reset = ax88772_link_reset, 858 .reset = ax88772_link_reset, 859 .flags = FLAG_ETHER | FLAG_FRAMING_AX, 860 .rx_fixup = ax88772_rx_fixup, 861 .tx_fixup = ax88772_tx_fixup, 862 .data = 0x00130103, 863}; 864 865static const struct usb_device_id products [] = { 866{ 867 // Linksys USB200M 868 USB_DEVICE (0x077b, 0x2226), 869 .driver_info = (unsigned long) &ax8817x_info, 870}, { 871 // Netgear FA120 872 USB_DEVICE (0x0846, 0x1040), 873 .driver_info = (unsigned long) &netgear_fa120_info, 874}, { 875 // DLink DUB-E100 876 USB_DEVICE (0x2001, 0x1a00), 877 .driver_info = (unsigned long) &dlink_dub_e100_info, 878}, { 879 // Intellinet, ST Lab USB Ethernet 880 USB_DEVICE (0x0b95, 0x1720), 881 .driver_info = (unsigned long) &ax8817x_info, 882}, { 883 // Hawking UF200, TrendNet TU2-ET100 884 USB_DEVICE (0x07b8, 0x420a), 885 .driver_info = (unsigned long) &hawking_uf200_info, 886}, { 887 // Billionton Systems, USB2AR 888 USB_DEVICE (0x08dd, 0x90ff), 889 .driver_info = (unsigned long) &ax8817x_info, 890}, { 891 // ATEN UC210T 892 USB_DEVICE (0x0557, 0x2009), 893 .driver_info = (unsigned long) &ax8817x_info, 894}, { 895 // Buffalo LUA-U2-KTX 896 USB_DEVICE (0x0411, 0x003d), 897 .driver_info = (unsigned long) &ax8817x_info, 898}, { 899 // Sitecom LN-029 "USB 2.0 10/100 Ethernet adapter" 900 USB_DEVICE (0x6189, 0x182d), 901 .driver_info = (unsigned long) &ax8817x_info, 902}, { 903 // corega FEther USB2-TX 904 USB_DEVICE (0x07aa, 0x0017), 905 .driver_info = (unsigned long) &ax8817x_info, 906}, { 907 // Surecom EP-1427X-2 908 USB_DEVICE (0x1189, 0x0893), 909 .driver_info = (unsigned long) &ax8817x_info, 910}, { 911 // goodway corp usb gwusb2e 912 USB_DEVICE (0x1631, 0x6200), 913 .driver_info = (unsigned long) &ax8817x_info, 914}, { 915 // ASIX AX88772 10/100 916 USB_DEVICE (0x0b95, 0x7720), 917 .driver_info = (unsigned long) &ax88772_info, 918}, 919 { }, // END 920}; 921MODULE_DEVICE_TABLE(usb, products); 922 923static struct usb_driver asix_driver = { 924 .owner = THIS_MODULE, 925 .name = "asix", 926 .id_table = products, 927 .probe = usbnet_probe, 928 .suspend = usbnet_suspend, 929 .resume = usbnet_resume, 930 .disconnect = usbnet_disconnect, 931}; 932 933static int __init asix_init(void) 934{ 935 return usb_register(&asix_driver); 936} 937module_init(asix_init); 938 939static void __exit asix_exit(void) 940{ 941 usb_deregister(&asix_driver); 942} 943module_exit(asix_exit); 944 945MODULE_AUTHOR("David Hollis"); 946MODULE_DESCRIPTION("ASIX AX8817X based USB 2.0 Ethernet Devices"); 947MODULE_LICENSE("GPL"); 948