# This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.674 -> 1.675 # drivers/usb/net/rtl8150.c 1.12 -> 1.13 # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 02/10/02 petkan@users.sourceforge.net 1.675 # [PATCH] USB: rtl8150 update # # set_mac_address is now added to the driver. thanks to Orjan Friberg # the actual writing to the eeprom is disabled by default # -------------------------------------------- # diff -Nru a/drivers/usb/net/rtl8150.c b/drivers/usb/net/rtl8150.c --- a/drivers/usb/net/rtl8150.c Wed Oct 2 22:40:47 2002 +++ b/drivers/usb/net/rtl8150.c Wed Oct 2 22:40:47 2002 @@ -21,11 +21,11 @@ #include /* Version Information */ -#define DRIVER_VERSION "v0.5.5 (2002/07/22)" +#define DRIVER_VERSION "v0.5.6 (2002/09/19)" #define DRIVER_AUTHOR "Petko Manolov " #define DRIVER_DESC "rtl8150 based usb-ethernet driver" -#define IRD 0x0120 +#define IDR 0x0120 #define MAR 0x0126 #define CR 0x012e #define TCR 0x012f @@ -45,6 +45,8 @@ #define ANLP 0x0146 #define AER 0x0148 +#define IDR_EEPROM 0x1202 + #define PHY_READ 0 #define PHY_WRITE 0x20 #define PHY_GO 0x40 @@ -73,6 +75,8 @@ #define PRODUCT_ID_RTL8150 0x8150 #define PRODUCT_ID_LUAKTX 0x0012 +#undef EEPROM_WRITE + /* table of devices that work with this driver */ static struct usb_device_id rtl8150_table[] = { {USB_DEVICE(VENDOR_ID_REALTEK, PRODUCT_ID_RTL8150)}, @@ -111,7 +115,7 @@ static inline struct sk_buff *pull_skb(rtl8150_t *); static void rtl8150_disconnect(struct usb_interface *intf); static int rtl8150_probe(struct usb_interface *intf, - const struct usb_device_id *id); + const struct usb_device_id *id); static struct usb_driver rtl8150_driver = { .name = "rtl8150", @@ -231,10 +235,51 @@ { u8 node_id[6]; - get_registers(dev, IRD, sizeof(node_id), node_id); + get_registers(dev, IDR, sizeof(node_id), node_id); memcpy(dev->netdev->dev_addr, node_id, sizeof(node_id)); } +static int rtl8150_set_mac_address(struct net_device *netdev, void *p) +{ + struct sockaddr *addr = p; + rtl8150_t *dev; + int i; + + if (netif_running(netdev)) + return -EBUSY; + dev = netdev->priv; + if (dev == NULL) { + return -ENODEV; + } + memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); + dbg("%s: Setting MAC address to ", netdev->name); + for (i = 0; i < 5; i++) + dbg("%02X:", netdev->dev_addr[i]); + dbg("%02X\n", netdev->dev_addr[i]); + /* Set the IDR registers. */ + set_registers(dev, IDR, sizeof(netdev->dev_addr), netdev->dev_addr); +#ifdef EEPROM_WRITE + { + u8 cr; + /* Get the CR contents. */ + get_registers(dev, CR, 1, &cr); + /* Set the WEPROM bit (eeprom write enable). */ + cr |= 0x20; + set_registers(dev, CR, 1, &cr); + /* Write the MAC address into eeprom. Eeprom writes must be word-sized, + so we need to split them up. */ + for (i = 0; i * 2 < netdev->addr_len; i++) { + set_registers(dev, IDR_EEPROM + (i * 2), 2, + netdev->dev_addr + (i * 2)); + } + /* Clear the WEPROM bit (preventing accidental eeprom writes). */ + cr &= 0xdf; + set_registers(dev, CR, 1, &cr); + } +#endif + return 0; +} + static int rtl8150_reset(rtl8150_t * dev) { u8 data = 0x10; @@ -764,6 +809,7 @@ netdev->tx_timeout = rtl8150_tx_timeout; netdev->hard_start_xmit = rtl8150_start_xmit; netdev->set_multicast_list = rtl8150_set_multicast; + netdev->set_mac_address = rtl8150_set_mac_address; netdev->get_stats = rtl8150_netdev_stats; netdev->mtu = RTL8150_MTU; dev->intr_interval = 100; /* 100ms */ @@ -782,7 +828,7 @@ info("%s: rtl8150 is detected", netdev->name); up(&dev->sem); - dev_set_drvdata (&intf->dev, dev); + dev_set_drvdata(&intf->dev, dev); return 0; err: unregister_netdev(dev->netdev); @@ -794,10 +840,9 @@ static void rtl8150_disconnect(struct usb_interface *intf) { - rtl8150_t *dev = dev_get_drvdata (&intf->dev); - - dev_set_drvdata (&intf->dev, NULL); + rtl8150_t *dev = dev_get_drvdata(&intf->dev); + dev_set_drvdata(&intf->dev, NULL); if (dev) { set_bit(RTL8150_UNPLUG, &dev->flags); unregister_netdev(dev->netdev);