catc.c (3c69a99b62fde9de86a612ef1daaa07d95f0a773) | catc.c (efe3e6b5aeefaabed9ad5dcb3682b581bf34c187) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Copyright (c) 2001 Vojtech Pavlik 4 * 5 * CATC EL1210A NetMate USB Ethernet driver 6 * 7 * Sponsored by SuSE 8 * 9 * Based on the work of 10 * Donald Becker | 1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Copyright (c) 2001 Vojtech Pavlik 4 * 5 * CATC EL1210A NetMate USB Ethernet driver 6 * 7 * Sponsored by SuSE 8 * 9 * Based on the work of 10 * Donald Becker |
11 * | 11 * |
12 * Old chipset support added by Simon Evans <spse@secret.org.uk> 2002 13 * - adds support for Belkin F5U011 14 */ 15 16/* | 12 * Old chipset support added by Simon Evans <spse@secret.org.uk> 2002 13 * - adds support for Belkin F5U011 14 */ 15 16/* |
17 * | 17 * |
18 * Should you need to contact me, the author, you can do so either by 19 * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail: 20 * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic 21 */ 22 23#include <linux/module.h> 24#include <linux/kernel.h> 25#include <linux/string.h> --- 23 unchanged lines hidden (view full) --- 49MODULE_AUTHOR(DRIVER_AUTHOR); 50MODULE_DESCRIPTION(DRIVER_DESC); 51MODULE_LICENSE("GPL"); 52 53static const char driver_name[] = "catc"; 54 55/* 56 * Some defines. | 18 * Should you need to contact me, the author, you can do so either by 19 * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail: 20 * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic 21 */ 22 23#include <linux/module.h> 24#include <linux/kernel.h> 25#include <linux/string.h> --- 23 unchanged lines hidden (view full) --- 49MODULE_AUTHOR(DRIVER_AUTHOR); 50MODULE_DESCRIPTION(DRIVER_DESC); 51MODULE_LICENSE("GPL"); 52 53static const char driver_name[] = "catc"; 54 55/* 56 * Some defines. |
57 */ | 57 */ |
58 59#define STATS_UPDATE (HZ) /* Time between stats updates */ 60#define TX_TIMEOUT (5*HZ) /* Max time the queue can be stopped */ 61#define PKT_SZ 1536 /* Max Ethernet packet size */ 62#define RX_MAX_BURST 15 /* Max packets per rx buffer (> 0, < 16) */ 63#define TX_MAX_BURST 15 /* Max full sized packets per tx buffer (> 0) */ 64#define CTRL_QUEUE 16 /* Max control requests in flight (power of two) */ 65#define RX_PKT_SZ 1600 /* Max size of receive packet for F5U011 */ --- 209 unchanged lines hidden (view full) --- 275 } 276} 277 278static void catc_irq_done(struct urb *urb) 279{ 280 struct catc *catc = urb->context; 281 u8 *data = urb->transfer_buffer; 282 int status = urb->status; | 58 59#define STATS_UPDATE (HZ) /* Time between stats updates */ 60#define TX_TIMEOUT (5*HZ) /* Max time the queue can be stopped */ 61#define PKT_SZ 1536 /* Max Ethernet packet size */ 62#define RX_MAX_BURST 15 /* Max packets per rx buffer (> 0, < 16) */ 63#define TX_MAX_BURST 15 /* Max full sized packets per tx buffer (> 0) */ 64#define CTRL_QUEUE 16 /* Max control requests in flight (power of two) */ 65#define RX_PKT_SZ 1600 /* Max size of receive packet for F5U011 */ --- 209 unchanged lines hidden (view full) --- 275 } 276} 277 278static void catc_irq_done(struct urb *urb) 279{ 280 struct catc *catc = urb->context; 281 u8 *data = urb->transfer_buffer; 282 int status = urb->status; |
283 unsigned int hasdata = 0, linksts = LinkNoChange; | 283 unsigned int hasdata, linksts = LinkNoChange; |
284 int res; 285 286 if (!catc->is_f5u011) { 287 hasdata = data[1] & 0x80; 288 if (data[1] & 0x40) 289 linksts = LinkGood; 290 else if (data[1] & 0x20) 291 linksts = LinkBad; --- 35 unchanged lines hidden (view full) --- 327 if (catc->is_f5u011) 328 atomic_inc(&catc->recq_sz); 329 } else { 330 catc->rx_urb->dev = catc->usbdev; 331 if ((res = usb_submit_urb(catc->rx_urb, GFP_ATOMIC)) < 0) { 332 dev_err(&catc->usbdev->dev, 333 "submit(rx_urb) status %d\n", res); 334 } | 284 int res; 285 286 if (!catc->is_f5u011) { 287 hasdata = data[1] & 0x80; 288 if (data[1] & 0x40) 289 linksts = LinkGood; 290 else if (data[1] & 0x20) 291 linksts = LinkBad; --- 35 unchanged lines hidden (view full) --- 327 if (catc->is_f5u011) 328 atomic_inc(&catc->recq_sz); 329 } else { 330 catc->rx_urb->dev = catc->usbdev; 331 if ((res = usb_submit_urb(catc->rx_urb, GFP_ATOMIC)) < 0) { 332 dev_err(&catc->usbdev->dev, 333 "submit(rx_urb) status %d\n", res); 334 } |
335 } | 335 } |
336 } 337resubmit: 338 res = usb_submit_urb (urb, GFP_ATOMIC); 339 if (res) 340 dev_err(&catc->usbdev->dev, 341 "can't resubmit intr, %s-%s, status %d\n", 342 catc->usbdev->bus->bus_name, 343 catc->usbdev->devpath, res); --- 189 unchanged lines hidden (view full) --- 533static int catc_ctrl_async(struct catc *catc, u8 dir, u8 request, u16 value, 534 u16 index, void *buf, int len, void (*callback)(struct catc *catc, struct ctrl_queue *q)) 535{ 536 struct ctrl_queue *q; 537 int retval = 0; 538 unsigned long flags; 539 540 spin_lock_irqsave(&catc->ctrl_lock, flags); | 336 } 337resubmit: 338 res = usb_submit_urb (urb, GFP_ATOMIC); 339 if (res) 340 dev_err(&catc->usbdev->dev, 341 "can't resubmit intr, %s-%s, status %d\n", 342 catc->usbdev->bus->bus_name, 343 catc->usbdev->devpath, res); --- 189 unchanged lines hidden (view full) --- 533static int catc_ctrl_async(struct catc *catc, u8 dir, u8 request, u16 value, 534 u16 index, void *buf, int len, void (*callback)(struct catc *catc, struct ctrl_queue *q)) 535{ 536 struct ctrl_queue *q; 537 int retval = 0; 538 unsigned long flags; 539 540 spin_lock_irqsave(&catc->ctrl_lock, flags); |
541 | 541 |
542 q = catc->ctrl_queue + catc->ctrl_head; 543 544 q->dir = dir; 545 q->request = request; 546 q->value = value; 547 q->index = index; 548 q->buf = buf; 549 q->len = len; --- 84 unchanged lines hidden (view full) --- 634 memset(catc->multicast, 0, 64); 635 636 catc_multicast(broadcast, catc->multicast); 637 catc_multicast(netdev->dev_addr, catc->multicast); 638 639 if (netdev->flags & IFF_PROMISC) { 640 memset(catc->multicast, 0xff, 64); 641 rx |= (!catc->is_f5u011) ? RxPromisc : AltRxPromisc; | 542 q = catc->ctrl_queue + catc->ctrl_head; 543 544 q->dir = dir; 545 q->request = request; 546 q->value = value; 547 q->index = index; 548 q->buf = buf; 549 q->len = len; --- 84 unchanged lines hidden (view full) --- 634 memset(catc->multicast, 0, 64); 635 636 catc_multicast(broadcast, catc->multicast); 637 catc_multicast(netdev->dev_addr, catc->multicast); 638 639 if (netdev->flags & IFF_PROMISC) { 640 memset(catc->multicast, 0xff, 64); 641 rx |= (!catc->is_f5u011) ? RxPromisc : AltRxPromisc; |
642 } | 642 } |
643 644 if (netdev->flags & IFF_ALLMULTI) { 645 memset(catc->multicast, 0xff, 64); 646 } else { 647 netdev_for_each_mc_addr(ha, netdev) { 648 u32 crc = ether_crc_le(6, ha->addr); 649 if (!catc->is_f5u011) { 650 catc->multicast[(crc >> 3) & 0x3f] |= 1 << (crc & 7); --- 150 unchanged lines hidden (view full) --- 801 spin_lock_init(&catc->ctrl_lock); 802 803 timer_setup(&catc->timer, catc_stats_timer, 0); 804 805 catc->ctrl_urb = usb_alloc_urb(0, GFP_KERNEL); 806 catc->tx_urb = usb_alloc_urb(0, GFP_KERNEL); 807 catc->rx_urb = usb_alloc_urb(0, GFP_KERNEL); 808 catc->irq_urb = usb_alloc_urb(0, GFP_KERNEL); | 643 644 if (netdev->flags & IFF_ALLMULTI) { 645 memset(catc->multicast, 0xff, 64); 646 } else { 647 netdev_for_each_mc_addr(ha, netdev) { 648 u32 crc = ether_crc_le(6, ha->addr); 649 if (!catc->is_f5u011) { 650 catc->multicast[(crc >> 3) & 0x3f] |= 1 << (crc & 7); --- 150 unchanged lines hidden (view full) --- 801 spin_lock_init(&catc->ctrl_lock); 802 803 timer_setup(&catc->timer, catc_stats_timer, 0); 804 805 catc->ctrl_urb = usb_alloc_urb(0, GFP_KERNEL); 806 catc->tx_urb = usb_alloc_urb(0, GFP_KERNEL); 807 catc->rx_urb = usb_alloc_urb(0, GFP_KERNEL); 808 catc->irq_urb = usb_alloc_urb(0, GFP_KERNEL); |
809 if ((!catc->ctrl_urb) || (!catc->tx_urb) || | 809 if ((!catc->ctrl_urb) || (!catc->tx_urb) || |
810 (!catc->rx_urb) || (!catc->irq_urb)) { 811 dev_err(&intf->dev, "No free urbs available.\n"); 812 ret = -ENOMEM; 813 goto fail_free; 814 } 815 816 /* The F5U011 has the same vendor/product as the netmate but a device version of 0x130 */ | 810 (!catc->rx_urb) || (!catc->irq_urb)) { 811 dev_err(&intf->dev, "No free urbs available.\n"); 812 ret = -ENOMEM; 813 goto fail_free; 814 } 815 816 /* The F5U011 has the same vendor/product as the netmate but a device version of 0x130 */ |
817 if (le16_to_cpu(usbdev->descriptor.idVendor) == 0x0423 && | 817 if (le16_to_cpu(usbdev->descriptor.idVendor) == 0x0423 && |
818 le16_to_cpu(usbdev->descriptor.idProduct) == 0xa && 819 le16_to_cpu(catc->usbdev->descriptor.bcdDevice) == 0x0130) { 820 dev_dbg(dev, "Testing for f5u011\n"); | 818 le16_to_cpu(usbdev->descriptor.idProduct) == 0xa && 819 le16_to_cpu(catc->usbdev->descriptor.bcdDevice) == 0x0130) { 820 dev_dbg(dev, "Testing for f5u011\n"); |
821 catc->is_f5u011 = 1; | 821 catc->is_f5u011 = 1; |
822 atomic_set(&catc->recq_sz, 0); 823 pktsz = RX_PKT_SZ; 824 } else { 825 pktsz = RX_MAX_BURST * (PKT_SZ + 2); 826 } | 822 atomic_set(&catc->recq_sz, 0); 823 pktsz = RX_PKT_SZ; 824 } else { 825 pktsz = RX_MAX_BURST * (PKT_SZ + 2); 826 } |
827 | 827 |
828 usb_fill_control_urb(catc->ctrl_urb, usbdev, usb_sndctrlpipe(usbdev, 0), 829 NULL, NULL, 0, catc_ctrl_done, catc); 830 831 usb_fill_bulk_urb(catc->tx_urb, usbdev, usb_sndbulkpipe(usbdev, 1), 832 NULL, 0, catc_tx_done, catc); 833 834 usb_fill_bulk_urb(catc->rx_urb, usbdev, usb_rcvbulkpipe(usbdev, 1), 835 catc->rx_buf, pktsz, catc_rx_done, catc); --- 13 unchanged lines hidden (view full) --- 849 goto fail_free; 850 } 851 852 *buf = 0x12345678; 853 catc_write_mem(catc, 0x7a80, buf, 4); 854 *buf = 0x87654321; 855 catc_write_mem(catc, 0xfa80, buf, 4); 856 catc_read_mem(catc, 0x7a80, buf, 4); | 828 usb_fill_control_urb(catc->ctrl_urb, usbdev, usb_sndctrlpipe(usbdev, 0), 829 NULL, NULL, 0, catc_ctrl_done, catc); 830 831 usb_fill_bulk_urb(catc->tx_urb, usbdev, usb_sndbulkpipe(usbdev, 1), 832 NULL, 0, catc_tx_done, catc); 833 834 usb_fill_bulk_urb(catc->rx_urb, usbdev, usb_rcvbulkpipe(usbdev, 1), 835 catc->rx_buf, pktsz, catc_rx_done, catc); --- 13 unchanged lines hidden (view full) --- 849 goto fail_free; 850 } 851 852 *buf = 0x12345678; 853 catc_write_mem(catc, 0x7a80, buf, 4); 854 *buf = 0x87654321; 855 catc_write_mem(catc, 0xfa80, buf, 4); 856 catc_read_mem(catc, 0x7a80, buf, 4); |
857 | 857 |
858 switch (*buf) { 859 case 0x12345678: 860 catc_set_reg(catc, TxBufCount, 8); 861 catc_set_reg(catc, RxBufCount, 32); 862 dev_dbg(dev, "64k Memory\n"); 863 break; 864 default: 865 dev_warn(&intf->dev, 866 "Couldn't detect memory size, assuming 32k\n"); 867 fallthrough; 868 case 0x87654321: 869 catc_set_reg(catc, TxBufCount, 4); 870 catc_set_reg(catc, RxBufCount, 16); 871 dev_dbg(dev, "32k Memory\n"); 872 break; 873 } 874 875 kfree(buf); | 858 switch (*buf) { 859 case 0x12345678: 860 catc_set_reg(catc, TxBufCount, 8); 861 catc_set_reg(catc, RxBufCount, 32); 862 dev_dbg(dev, "64k Memory\n"); 863 break; 864 default: 865 dev_warn(&intf->dev, 866 "Couldn't detect memory size, assuming 32k\n"); 867 fallthrough; 868 case 0x87654321: 869 catc_set_reg(catc, TxBufCount, 4); 870 catc_set_reg(catc, RxBufCount, 16); 871 dev_dbg(dev, "32k Memory\n"); 872 break; 873 } 874 875 kfree(buf); |
876 | 876 |
877 dev_dbg(dev, "Getting MAC from SEEROM.\n"); | 877 dev_dbg(dev, "Getting MAC from SEEROM.\n"); |
878 | 878 |
879 catc_get_mac(catc, macbuf); 880 eth_hw_addr_set(netdev, macbuf); | 879 catc_get_mac(catc, macbuf); 880 eth_hw_addr_set(netdev, macbuf); |
881 | 881 |
882 dev_dbg(dev, "Setting MAC into registers.\n"); | 882 dev_dbg(dev, "Setting MAC into registers.\n"); |
883 | 883 |
884 for (i = 0; i < 6; i++) 885 catc_set_reg(catc, StationAddr0 - i, netdev->dev_addr[i]); | 884 for (i = 0; i < 6; i++) 885 catc_set_reg(catc, StationAddr0 - i, netdev->dev_addr[i]); |
886 | 886 |
887 dev_dbg(dev, "Filling the multicast list.\n"); | 887 dev_dbg(dev, "Filling the multicast list.\n"); |
888 | 888 |
889 eth_broadcast_addr(broadcast); 890 catc_multicast(broadcast, catc->multicast); 891 catc_multicast(netdev->dev_addr, catc->multicast); 892 catc_write_mem(catc, 0xfa80, catc->multicast, 64); | 889 eth_broadcast_addr(broadcast); 890 catc_multicast(broadcast, catc->multicast); 891 catc_multicast(netdev->dev_addr, catc->multicast); 892 catc_write_mem(catc, 0xfa80, catc->multicast, 64); |
893 | 893 |
894 dev_dbg(dev, "Clearing error counters.\n"); | 894 dev_dbg(dev, "Clearing error counters.\n"); |
895 | 895 |
896 for (i = 0; i < 8; i++) 897 catc_set_reg(catc, EthStats + i, 0); 898 catc->last_stats = jiffies; | 896 for (i = 0; i < 8; i++) 897 catc_set_reg(catc, EthStats + i, 0); 898 catc->last_stats = jiffies; |
899 | 899 |
900 dev_dbg(dev, "Enabling.\n"); | 900 dev_dbg(dev, "Enabling.\n"); |
901 | 901 |
902 catc_set_reg(catc, MaxBurst, RX_MAX_BURST); 903 catc_set_reg(catc, OpModes, OpTxMerge | OpRxMerge | OpLenInclude | Op3MemWaits); 904 catc_set_reg(catc, LEDCtrl, LEDLink); 905 catc_set_reg(catc, RxUnit, RxEnable | RxPolarity | RxMultiCast); 906 } else { 907 dev_dbg(dev, "Performing reset\n"); 908 catc_reset(catc); 909 catc_get_mac(catc, macbuf); 910 eth_hw_addr_set(netdev, macbuf); | 902 catc_set_reg(catc, MaxBurst, RX_MAX_BURST); 903 catc_set_reg(catc, OpModes, OpTxMerge | OpRxMerge | OpLenInclude | Op3MemWaits); 904 catc_set_reg(catc, LEDCtrl, LEDLink); 905 catc_set_reg(catc, RxUnit, RxEnable | RxPolarity | RxMultiCast); 906 } else { 907 dev_dbg(dev, "Performing reset\n"); 908 catc_reset(catc); 909 catc_get_mac(catc, macbuf); 910 eth_hw_addr_set(netdev, macbuf); |
911 | 911 |
912 dev_dbg(dev, "Setting RX Mode\n"); 913 catc->rxmode[0] = RxEnable | RxPolarity | RxMultiCast; 914 catc->rxmode[1] = 0; 915 f5u011_rxmode(catc, catc->rxmode); 916 } 917 dev_dbg(dev, "Init done.\n"); 918 printk(KERN_INFO "%s: %s USB Ethernet at usb-%s-%s, %pM.\n", 919 netdev->name, (catc->is_f5u011) ? "Belkin F5U011" : "CATC EL1210A NetMate", --- 62 unchanged lines hidden --- | 912 dev_dbg(dev, "Setting RX Mode\n"); 913 catc->rxmode[0] = RxEnable | RxPolarity | RxMultiCast; 914 catc->rxmode[1] = 0; 915 f5u011_rxmode(catc, catc->rxmode); 916 } 917 dev_dbg(dev, "Init done.\n"); 918 printk(KERN_INFO "%s: %s USB Ethernet at usb-%s-%s, %pM.\n", 919 netdev->name, (catc->is_f5u011) ? "Belkin F5U011" : "CATC EL1210A NetMate", --- 62 unchanged lines hidden --- |