2019-05-19 16:51:43 +03:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2005-08-31 20:54:50 +04:00
|
|
|
/*
|
|
|
|
* PL-2301/2302 USB host-to-host link cables
|
|
|
|
* Copyright (C) 2000-2005 by David Brownell
|
|
|
|
*/
|
|
|
|
|
|
|
|
// #define DEBUG // error path messages, extra info
|
|
|
|
// #define VERBOSE // more; success messages
|
|
|
|
|
|
|
|
#include <linux/module.h>
|
|
|
|
#include <linux/netdevice.h>
|
|
|
|
#include <linux/etherdevice.h>
|
|
|
|
#include <linux/ethtool.h>
|
|
|
|
#include <linux/workqueue.h>
|
|
|
|
#include <linux/mii.h>
|
|
|
|
#include <linux/usb.h>
|
2008-01-26 01:51:45 +03:00
|
|
|
#include <linux/usb/usbnet.h>
|
2005-08-31 20:54:50 +04:00
|
|
|
|
|
|
|
|
|
|
|
/*
|
2010-10-18 13:03:14 +04:00
|
|
|
* Prolific PL-2301/PL-2302 driver ... http://www.prolific.com.tw/
|
2005-08-31 20:54:50 +04:00
|
|
|
*
|
|
|
|
* The protocol and handshaking used here should be bug-compatible
|
|
|
|
* with the Linux 2.2 "plusb" driver, by Deti Fliegl.
|
|
|
|
*
|
|
|
|
* HEADS UP: this handshaking isn't all that robust. This driver
|
|
|
|
* gets confused easily if you unplug one end of the cable then
|
|
|
|
* try to connect it again; you'll need to restart both ends. The
|
2016-03-28 02:58:15 +03:00
|
|
|
* "naplink" software (used by some PlayStation/2 developers) does
|
2005-08-31 20:54:50 +04:00
|
|
|
* the handshaking much better! Also, sometimes this hardware
|
|
|
|
* seems to get wedged under load. Prolific docs are weak, and
|
|
|
|
* don't identify differences between PL2301 and PL2302, much less
|
|
|
|
* anything to explain the different PL2302 versions observed.
|
2011-04-07 01:40:14 +04:00
|
|
|
*
|
|
|
|
* NOTE: pl2501 has several modes, including pl2301 and pl2302
|
|
|
|
* compatibility. Some docs suggest the difference between 2301
|
|
|
|
* and 2302 is only to make MS-Windows use a different driver...
|
|
|
|
*
|
|
|
|
* pl25a1 glue based on patch from Tony Gibbs. Prolific "docs" on
|
|
|
|
* this chip are as usual incomplete about what control messages
|
|
|
|
* are supported.
|
2005-08-31 20:54:50 +04:00
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Bits 0-4 can be used for software handshaking; they're set from
|
|
|
|
* one end, cleared from the other, "read" with the interrupt byte.
|
|
|
|
*/
|
|
|
|
#define PL_S_EN (1<<7) /* (feature only) suspend enable */
|
|
|
|
/* reserved bit -- rx ready (6) ? */
|
|
|
|
#define PL_TX_READY (1<<5) /* (interrupt only) transmit ready */
|
|
|
|
#define PL_RESET_OUT (1<<4) /* reset output pipe */
|
|
|
|
#define PL_RESET_IN (1<<3) /* reset input pipe */
|
|
|
|
#define PL_TX_C (1<<2) /* transmission complete */
|
|
|
|
#define PL_TX_REQ (1<<1) /* transmission received */
|
|
|
|
#define PL_PEER_E (1<<0) /* peer exists */
|
|
|
|
|
|
|
|
static inline int
|
|
|
|
pl_vendor_req(struct usbnet *dev, u8 req, u8 val, u8 index)
|
|
|
|
{
|
2012-10-24 23:47:01 +04:00
|
|
|
return usbnet_read_cmd(dev, req,
|
|
|
|
USB_DIR_IN | USB_TYPE_VENDOR |
|
|
|
|
USB_RECIP_DEVICE,
|
|
|
|
val, index, NULL, 0);
|
2005-08-31 20:54:50 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline int
|
|
|
|
pl_clear_QuickLink_features(struct usbnet *dev, int val)
|
|
|
|
{
|
|
|
|
return pl_vendor_req(dev, 1, (u8) val, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int
|
|
|
|
pl_set_QuickLink_features(struct usbnet *dev, int val)
|
|
|
|
{
|
|
|
|
return pl_vendor_req(dev, 3, (u8) val, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int pl_reset(struct usbnet *dev)
|
|
|
|
{
|
2011-04-07 01:40:15 +04:00
|
|
|
int status;
|
|
|
|
|
2005-08-31 20:54:50 +04:00
|
|
|
/* some units seem to need this reset, others reject it utterly.
|
|
|
|
* FIXME be more like "naplink" or windows drivers.
|
|
|
|
*/
|
2011-04-07 01:40:15 +04:00
|
|
|
status = pl_set_QuickLink_features(dev,
|
2005-08-31 20:54:50 +04:00
|
|
|
PL_S_EN|PL_RESET_OUT|PL_RESET_IN|PL_PEER_E);
|
2011-04-07 01:40:15 +04:00
|
|
|
if (status != 0 && netif_msg_probe(dev))
|
|
|
|
netif_dbg(dev, link, dev->net, "pl_reset --> %d\n", status);
|
2005-08-31 20:54:50 +04:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct driver_info prolific_info = {
|
2017-04-20 13:04:10 +03:00
|
|
|
.description = "Prolific PL-2301/PL-2302/PL-25A1/PL-27A1",
|
usbnet: use eth%d name for known ethernet devices
The documentation for the USB ethernet devices suggests that
only some devices are supposed to use usb0 as the network interface
name instead of eth0. The logic used there, and documented in
Kconfig for CDC is that eth0 will be used when the mac address
is a globally assigned one, but usb0 is used for the locally
managed range that is typically used on point-to-point links.
Unfortunately, this has caused a lot of pain on the smsc95xx
device that is used on the popular pandaboard without an
EEPROM to store the MAC address, which causes the driver to
call random_ether_address().
Obviously, there should be a proper MAC addressed assigned to
the device, and discussions are ongoing about how to solve
this, but this patch at least makes sure that the default
interface naming gets a little saner and matches what the
user can expect based on the documentation, including for
new devices.
The approach taken here is to flag whether a device might be a
point-to-point link with the new FLAG_POINTTOPOINT setting in
the usbnet driver_info. A driver can set both FLAG_POINTTOPOINT
and FLAG_ETHER if it is not sure (e.g. cdc_ether), or just one
of the two. The usbnet framework only looks at the MAC address
for device naming if both flags are set, otherwise it trusts the
flag.
Signed-off-by: Arnd Bergmann <arnd.bergmann@linaro.org>
Tested-by: Andy Green <andy.green@linaro.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2011-04-02 07:12:02 +04:00
|
|
|
.flags = FLAG_POINTTOPOINT | FLAG_NO_SETINT,
|
2005-08-31 20:54:50 +04:00
|
|
|
/* some PL-2302 versions seem to fail usb_set_interface() */
|
|
|
|
.reset = pl_reset,
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Proilific's name won't normally be on the cables, and
|
|
|
|
* may not be on the device.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static const struct usb_device_id products [] = {
|
|
|
|
|
2011-04-07 01:40:14 +04:00
|
|
|
/* full speed cables */
|
2005-08-31 20:54:50 +04:00
|
|
|
{
|
|
|
|
USB_DEVICE(0x067b, 0x0000), // PL-2301
|
|
|
|
.driver_info = (unsigned long) &prolific_info,
|
|
|
|
}, {
|
|
|
|
USB_DEVICE(0x067b, 0x0001), // PL-2302
|
|
|
|
.driver_info = (unsigned long) &prolific_info,
|
|
|
|
},
|
|
|
|
|
2011-04-07 01:40:14 +04:00
|
|
|
/* high speed cables */
|
|
|
|
{
|
|
|
|
USB_DEVICE(0x067b, 0x25a1), /* PL-25A1, no eeprom */
|
|
|
|
.driver_info = (unsigned long) &prolific_info,
|
|
|
|
}, {
|
|
|
|
USB_DEVICE(0x050d, 0x258a), /* Belkin F5U258/F5U279 (PL-25A1) */
|
|
|
|
.driver_info = (unsigned long) &prolific_info,
|
2015-02-16 22:47:06 +03:00
|
|
|
}, {
|
|
|
|
USB_DEVICE(0x3923, 0x7825), /* National Instruments USB
|
|
|
|
* Host-to-Host Cable
|
|
|
|
*/
|
|
|
|
.driver_info = (unsigned long) &prolific_info,
|
2017-04-20 13:04:10 +03:00
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
/* super speed cables */
|
|
|
|
{
|
|
|
|
USB_DEVICE(0x067b, 0x27a1), /* PL-27A1, no eeprom
|
|
|
|
* also: goobay Active USB 3.0
|
|
|
|
* Data Link,
|
|
|
|
* Unitek Y-3501
|
|
|
|
*/
|
|
|
|
.driver_info = (unsigned long) &prolific_info,
|
2011-04-07 01:40:14 +04:00
|
|
|
},
|
|
|
|
|
2005-08-31 20:54:50 +04:00
|
|
|
{ }, // END
|
|
|
|
};
|
|
|
|
MODULE_DEVICE_TABLE(usb, products);
|
|
|
|
|
|
|
|
static struct usb_driver plusb_driver = {
|
|
|
|
.name = "plusb",
|
|
|
|
.id_table = products,
|
|
|
|
.probe = usbnet_probe,
|
|
|
|
.disconnect = usbnet_disconnect,
|
|
|
|
.suspend = usbnet_suspend,
|
|
|
|
.resume = usbnet_resume,
|
2012-04-23 21:08:51 +04:00
|
|
|
.disable_hub_initiated_lpm = 1,
|
2005-08-31 20:54:50 +04:00
|
|
|
};
|
|
|
|
|
2011-11-18 21:44:20 +04:00
|
|
|
module_usb_driver(plusb_driver);
|
2005-08-31 20:54:50 +04:00
|
|
|
|
|
|
|
MODULE_AUTHOR("David Brownell");
|
2017-04-20 13:04:10 +03:00
|
|
|
MODULE_DESCRIPTION("Prolific PL-2301/2302/25A1/27A1 USB Host to Host Link Driver");
|
2005-08-31 20:54:50 +04:00
|
|
|
MODULE_LICENSE("GPL");
|