gl620a.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * GeneSys GL620USB-A based links
  4. * Copyright (C) 2001 by Jiun-Jie Huang <[email protected]>
  5. * Copyright (C) 2001 by Stanislav Brabec <[email protected]>
  6. */
  7. // #define DEBUG // error path messages, extra info
  8. // #define VERBOSE // more; success messages
  9. #include <linux/module.h>
  10. #include <linux/netdevice.h>
  11. #include <linux/etherdevice.h>
  12. #include <linux/ethtool.h>
  13. #include <linux/workqueue.h>
  14. #include <linux/mii.h>
  15. #include <linux/usb.h>
  16. #include <linux/usb/usbnet.h>
  17. #include <linux/gfp.h>
  18. /*
  19. * GeneSys GL620USB-A (www.genesyslogic.com.tw)
  20. *
  21. * ... should partially interop with the Win32 driver for this hardware.
  22. * The GeneSys docs imply there's some NDIS issue motivating this framing.
  23. *
  24. * Some info from GeneSys:
  25. * - GL620USB-A is full duplex; GL620USB is only half duplex for bulk.
  26. * (Some cables, like the BAFO-100c, use the half duplex version.)
  27. * - For the full duplex model, the low bit of the version code says
  28. * which side is which ("left/right").
  29. * - For the half duplex type, a control/interrupt handshake settles
  30. * the transfer direction. (That's disabled here, partially coded.)
  31. * A control URB would block until other side writes an interrupt.
  32. *
  33. * Original code from Jiun-Jie Huang <[email protected]>
  34. * and merged into "usbnet" by Stanislav Brabec <[email protected]>.
  35. */
  36. // control msg write command
  37. #define GENELINK_CONNECT_WRITE 0xF0
  38. // interrupt pipe index
  39. #define GENELINK_INTERRUPT_PIPE 0x03
  40. // interrupt read buffer size
  41. #define INTERRUPT_BUFSIZE 0x08
  42. // interrupt pipe interval value
  43. #define GENELINK_INTERRUPT_INTERVAL 0x10
  44. // max transmit packet number per transmit
  45. #define GL_MAX_TRANSMIT_PACKETS 32
  46. // max packet length
  47. #define GL_MAX_PACKET_LEN 1514
  48. // max receive buffer size
  49. #define GL_RCV_BUF_SIZE \
  50. (((GL_MAX_PACKET_LEN + 4) * GL_MAX_TRANSMIT_PACKETS) + 4)
  51. struct gl_packet {
  52. __le32 packet_length;
  53. char packet_data[];
  54. };
  55. struct gl_header {
  56. __le32 packet_count;
  57. struct gl_packet packets;
  58. };
  59. static int genelink_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
  60. {
  61. struct gl_header *header;
  62. struct gl_packet *packet;
  63. struct sk_buff *gl_skb;
  64. u32 size;
  65. u32 count;
  66. /* This check is no longer done by usbnet */
  67. if (skb->len < dev->net->hard_header_len)
  68. return 0;
  69. header = (struct gl_header *) skb->data;
  70. // get the packet count of the received skb
  71. count = le32_to_cpu(header->packet_count);
  72. if (count > GL_MAX_TRANSMIT_PACKETS) {
  73. netdev_dbg(dev->net,
  74. "genelink: invalid received packet count %u\n",
  75. count);
  76. return 0;
  77. }
  78. // set the current packet pointer to the first packet
  79. packet = &header->packets;
  80. // decrement the length for the packet count size 4 bytes
  81. skb_pull(skb, 4);
  82. while (count > 1) {
  83. // get the packet length
  84. size = le32_to_cpu(packet->packet_length);
  85. // this may be a broken packet
  86. if (size > GL_MAX_PACKET_LEN) {
  87. netdev_dbg(dev->net, "genelink: invalid rx length %d\n",
  88. size);
  89. return 0;
  90. }
  91. // allocate the skb for the individual packet
  92. gl_skb = alloc_skb(size, GFP_ATOMIC);
  93. if (gl_skb) {
  94. // copy the packet data to the new skb
  95. skb_put_data(gl_skb, packet->packet_data, size);
  96. usbnet_skb_return(dev, gl_skb);
  97. }
  98. // advance to the next packet
  99. packet = (struct gl_packet *)&packet->packet_data[size];
  100. count--;
  101. // shift the data pointer to the next gl_packet
  102. skb_pull(skb, size + 4);
  103. }
  104. // skip the packet length field 4 bytes
  105. skb_pull(skb, 4);
  106. if (skb->len > GL_MAX_PACKET_LEN) {
  107. netdev_dbg(dev->net, "genelink: invalid rx length %d\n",
  108. skb->len);
  109. return 0;
  110. }
  111. return 1;
  112. }
  113. static struct sk_buff *
  114. genelink_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
  115. {
  116. int padlen;
  117. int length = skb->len;
  118. int headroom = skb_headroom(skb);
  119. int tailroom = skb_tailroom(skb);
  120. __le32 *packet_count;
  121. __le32 *packet_len;
  122. // FIXME: magic numbers, bleech
  123. padlen = ((skb->len + (4 + 4*1)) % 64) ? 0 : 1;
  124. if ((!skb_cloned(skb))
  125. && ((headroom + tailroom) >= (padlen + (4 + 4*1)))) {
  126. if ((headroom < (4 + 4*1)) || (tailroom < padlen)) {
  127. skb->data = memmove(skb->head + (4 + 4*1),
  128. skb->data, skb->len);
  129. skb_set_tail_pointer(skb, skb->len);
  130. }
  131. } else {
  132. struct sk_buff *skb2;
  133. skb2 = skb_copy_expand(skb, (4 + 4*1) , padlen, flags);
  134. dev_kfree_skb_any(skb);
  135. skb = skb2;
  136. if (!skb)
  137. return NULL;
  138. }
  139. // attach the packet count to the header
  140. packet_count = skb_push(skb, (4 + 4 * 1));
  141. packet_len = packet_count + 1;
  142. *packet_count = cpu_to_le32(1);
  143. *packet_len = cpu_to_le32(length);
  144. // add padding byte
  145. if ((skb->len % dev->maxpacket) == 0)
  146. skb_put(skb, 1);
  147. return skb;
  148. }
  149. static int genelink_bind(struct usbnet *dev, struct usb_interface *intf)
  150. {
  151. dev->hard_mtu = GL_RCV_BUF_SIZE;
  152. dev->net->hard_header_len += 4;
  153. dev->in = usb_rcvbulkpipe(dev->udev, dev->driver_info->in);
  154. dev->out = usb_sndbulkpipe(dev->udev, dev->driver_info->out);
  155. return 0;
  156. }
  157. static const struct driver_info genelink_info = {
  158. .description = "Genesys GeneLink",
  159. .flags = FLAG_POINTTOPOINT | FLAG_FRAMING_GL | FLAG_NO_SETINT,
  160. .bind = genelink_bind,
  161. .rx_fixup = genelink_rx_fixup,
  162. .tx_fixup = genelink_tx_fixup,
  163. .in = 1, .out = 2,
  164. #ifdef GENELINK_ACK
  165. .check_connect =genelink_check_connect,
  166. #endif
  167. };
  168. static const struct usb_device_id products [] = {
  169. {
  170. USB_DEVICE(0x05e3, 0x0502), // GL620USB-A
  171. .driver_info = (unsigned long) &genelink_info,
  172. },
  173. /* NOT: USB_DEVICE(0x05e3, 0x0501), // GL620USB
  174. * that's half duplex, not currently supported
  175. */
  176. { }, // END
  177. };
  178. MODULE_DEVICE_TABLE(usb, products);
  179. static struct usb_driver gl620a_driver = {
  180. .name = "gl620a",
  181. .id_table = products,
  182. .probe = usbnet_probe,
  183. .disconnect = usbnet_disconnect,
  184. .suspend = usbnet_suspend,
  185. .resume = usbnet_resume,
  186. .disable_hub_initiated_lpm = 1,
  187. };
  188. module_usb_driver(gl620a_driver);
  189. MODULE_AUTHOR("Jiun-Jie Huang");
  190. MODULE_DESCRIPTION("GL620-USB-A Host-to-Host Link cables");
  191. MODULE_LICENSE("GPL");