net: usb: aqc111: Add implementation of read and write commands
authorDmitry Bezrukov <dmitry.bezrukov@aquantia.com>
Mon, 26 Nov 2018 09:33:04 +0000 (09:33 +0000)
committerDavid S. Miller <davem@davemloft.net>
Tue, 27 Nov 2018 23:46:06 +0000 (15:46 -0800)
Read/write command register defines and functions

Signed-off-by: Dmitry Bezrukov <dmitry.bezrukov@aquantia.com>
Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/usb/aqc111.c
drivers/net/usb/aqc111.h [new file with mode: 0644]

index a2628856c580596e61db06b26e7c0b87a09732d7..fbd48b8a6944fe1d33d8fbd237499fb70e7f4277 100644 (file)
 #include <linux/usb/cdc.h>
 #include <linux/usb/usbnet.h>
 
+#include "aqc111.h"
+
+static int aqc111_read_cmd_nopm(struct usbnet *dev, u8 cmd, u16 value,
+                               u16 index, u16 size, void *data)
+{
+       int ret;
+
+       ret = usbnet_read_cmd_nopm(dev, cmd, USB_DIR_IN | USB_TYPE_VENDOR |
+                                  USB_RECIP_DEVICE, value, index, data, size);
+
+       if (unlikely(ret < 0))
+               netdev_warn(dev->net,
+                           "Failed to read(0x%x) reg index 0x%04x: %d\n",
+                           cmd, index, ret);
+
+       return ret;
+}
+
+static int aqc111_read_cmd(struct usbnet *dev, u8 cmd, u16 value,
+                          u16 index, u16 size, void *data)
+{
+       int ret;
+
+       ret = usbnet_read_cmd(dev, cmd, USB_DIR_IN | USB_TYPE_VENDOR |
+                             USB_RECIP_DEVICE, value, index, data, size);
+
+       if (unlikely(ret < 0))
+               netdev_warn(dev->net,
+                           "Failed to read(0x%x) reg index 0x%04x: %d\n",
+                           cmd, index, ret);
+
+       return ret;
+}
+
+static int __aqc111_write_cmd(struct usbnet *dev, u8 cmd, u8 reqtype,
+                             u16 value, u16 index, u16 size, const void *data)
+{
+       int err = -ENOMEM;
+       void *buf = NULL;
+
+       netdev_dbg(dev->net,
+                  "%s cmd=%#x reqtype=%#x value=%#x index=%#x size=%d\n",
+                  __func__, cmd, reqtype, value, index, size);
+
+       if (data) {
+               buf = kmemdup(data, size, GFP_KERNEL);
+               if (!buf)
+                       goto out;
+       }
+
+       err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
+                             cmd, reqtype, value, index, buf, size,
+                             (cmd == AQ_PHY_POWER) ? AQ_USB_PHY_SET_TIMEOUT :
+                             AQ_USB_SET_TIMEOUT);
+
+       if (unlikely(err < 0))
+               netdev_warn(dev->net,
+                           "Failed to write(0x%x) reg index 0x%04x: %d\n",
+                           cmd, index, err);
+       kfree(buf);
+
+out:
+       return err;
+}
+
+static int aqc111_write_cmd_nopm(struct usbnet *dev, u8 cmd, u16 value,
+                                u16 index, u16 size, void *data)
+{
+       int ret;
+
+       ret = __aqc111_write_cmd(dev, cmd, USB_DIR_OUT | USB_TYPE_VENDOR |
+                                USB_RECIP_DEVICE, value, index, size, data);
+
+       return ret;
+}
+
+static int aqc111_write_cmd(struct usbnet *dev, u8 cmd, u16 value,
+                           u16 index, u16 size, void *data)
+{
+       int ret;
+
+       if (usb_autopm_get_interface(dev->intf) < 0)
+               return -ENODEV;
+
+       ret = __aqc111_write_cmd(dev, cmd, USB_DIR_OUT | USB_TYPE_VENDOR |
+                                USB_RECIP_DEVICE, value, index, size, data);
+
+       usb_autopm_put_interface(dev->intf);
+
+       return ret;
+}
+
 static const struct net_device_ops aqc111_netdev_ops = {
        .ndo_open               = usbnet_open,
        .ndo_stop               = usbnet_stop,
diff --git a/drivers/net/usb/aqc111.h b/drivers/net/usb/aqc111.h
new file mode 100644 (file)
index 0000000..f4302f7
--- /dev/null
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Aquantia Corp. Aquantia AQtion USB to 5GbE Controller
+ * Copyright (C) 2003-2005 David Hollis <dhollis@davehollis.com>
+ * Copyright (C) 2005 Phil Chang <pchang23@sbcglobal.net>
+ * Copyright (C) 2002-2003 TiVo Inc.
+ * Copyright (C) 2017-2018 ASIX
+ * Copyright (C) 2018 Aquantia Corp.
+ */
+
+#ifndef __LINUX_USBNET_AQC111_H
+#define __LINUX_USBNET_AQC111_H
+
+#define AQ_PHY_POWER                   0x31
+
+#define AQ_USB_PHY_SET_TIMEOUT         10000
+#define AQ_USB_SET_TIMEOUT             4000
+
+#endif /* __LINUX_USBNET_AQC111_H */