[PATCHv3] usb: gadget: f_fs: Allow scatter-gather buffers

2018-11-13 Thread Andrzej Pietrasiewicz
Some protocols implemented in userspace with FunctionFS might require large
buffers, e.g. 64kB or more. Currently the said memory is allocated with
kmalloc, which might fail should system memory be highly fragmented.

On the other hand, some UDC hardware allows scatter-gather operation and
this patch takes advantage of this capability: if the requested buffer
is larger than PAGE_SIZE and the UDC allows scatter-gather operation, then
the buffer is allocated with vmalloc and a scatterlist describing it is
created and passed to usb request.

Signed-off-by: Andrzej Pietrasiewicz 
---
v3:
- simplified calculating number of pages the vmalloc'ed buffer occupies
- simplified types in ffs_build_sg_list()
- whitespace corrections
v2:
- added include directives for kvmalloc_array and vmalloc

 drivers/usb/gadget/function/f_fs.c | 94 +++---
 1 file changed, 87 insertions(+), 7 deletions(-)

diff --git a/drivers/usb/gadget/function/f_fs.c 
b/drivers/usb/gadget/function/f_fs.c
index 3ada83d..c27bc05 100644
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -18,9 +18,12 @@
 #include 
 #include 
 #include 
+#include 
 #include 
+#include 
 #include 
 #include 
+#include 
 #include 
 
 #include 
@@ -219,6 +222,8 @@ struct ffs_io_data {
 
struct usb_ep *ep;
struct usb_request *req;
+   struct sg_table sgt;
+   bool use_sg;
 
struct ffs_data *ffs;
 };
@@ -750,6 +755,66 @@ static ssize_t ffs_copy_to_iter(void *data, int data_len, 
struct iov_iter *iter)
return ret;
 }
 
+/*
+ * allocate a virtually contiguous buffer and create a scatterlist describing 
it
+ * @sg_table   - pointer to a place to be filled with sg_table contents
+ * @size   - required buffer size
+ */
+static void *ffs_build_sg_list(struct sg_table *sg_table, size_t size)
+{
+   struct page **pages;
+   void *vaddr, *ptr;
+   unsigned int n_pages;
+   int i;
+
+   vaddr = vmalloc(size);
+   if (!vaddr)
+   return NULL;
+
+   n_pages = PAGE_ALIGN(size) >> PAGE_SHIFT;
+   pages = kvmalloc_array(n_pages, sizeof(struct page *), GFP_KERNEL);
+   if (!pages) {
+   vfree(vaddr);
+
+   return NULL;
+   }
+   for (i = 0, ptr = vaddr; i < n_pages; ++i, ptr += PAGE_SIZE)
+   pages[i] = vmalloc_to_page(ptr);
+
+   if (sg_alloc_table_from_pages(sg_table, pages, n_pages,
+   (unsigned long)vaddr, size, GFP_KERNEL)) {
+   kvfree(pages);
+   vfree(vaddr);
+
+   return NULL;
+   }
+   kvfree(pages);
+
+   return vaddr;
+}
+
+static inline void *ffs_alloc_buffer(struct ffs_io_data *io_data,
+   size_t data_len)
+{
+   if (io_data->use_sg)
+   return ffs_build_sg_list(&io_data->sgt, data_len);
+
+   return kmalloc(data_len, GFP_KERNEL);
+}
+
+static inline void ffs_free_buffer(struct ffs_io_data *io_data)
+{
+   if (!io_data->buf)
+   return;
+
+   if (io_data->use_sg) {
+   sg_free_table(&io_data->sgt);
+   vfree(io_data->buf);
+   } else {
+   kfree(io_data->buf);
+   }
+}
+
 static void ffs_user_copy_worker(struct work_struct *work)
 {
struct ffs_io_data *io_data = container_of(work, struct ffs_io_data,
@@ -777,7 +842,7 @@ static void ffs_user_copy_worker(struct work_struct *work)
 
if (io_data->read)
kfree(io_data->to_free);
-   kfree(io_data->buf);
+   ffs_free_buffer(io_data);
kfree(io_data);
 }
 
@@ -933,6 +998,7 @@ static ssize_t ffs_epfile_io(struct file *file, struct 
ffs_io_data *io_data)
 * earlier
 */
gadget = epfile->ffs->gadget;
+   io_data->use_sg = gadget->sg_supported && data_len > PAGE_SIZE;
 
spin_lock_irq(&epfile->ffs->eps_lock);
/* In the meantime, endpoint got disabled or changed. */
@@ -949,7 +1015,7 @@ static ssize_t ffs_epfile_io(struct file *file, struct 
ffs_io_data *io_data)
data_len = usb_ep_align_maybe(gadget, ep->ep, data_len);
spin_unlock_irq(&epfile->ffs->eps_lock);
 
-   data = kmalloc(data_len, GFP_KERNEL);
+   data = ffs_alloc_buffer(io_data, data_len);
if (unlikely(!data)) {
ret = -ENOMEM;
goto error_mutex;
@@ -989,8 +1055,16 @@ static ssize_t ffs_epfile_io(struct file *file, struct 
ffs_io_data *io_data)
bool interrupted = false;
 
req = ep->req;
-   req->buf  = data;
-   req->length   = data_len;
+   if (io_data->use_sg) {
+   req->buf = NULL;
+   req->sg = io_data->sgt.sgl;
+   req->num_sgs = io_data->sgt.nents;
+   } else {
+   req->buf

Re: [PATCH v2 2/3] spi: add FTDI MPSSE SPI controller driver

2018-11-13 Thread Mark Brown
On Sat, Nov 10, 2018 at 11:39:58AM +0100, Anatolij Gustschin wrote:

> This v2 patch is the only patch of the original series that was
> changed, I didn't resend whole series to avoid spamming the lists.

Please don't do this, the numbering for a patch series only makes sense
for ordering the patches within a series.  If you're just sending a
single patch then there's no need to number anything, or the patch
series hasn't been applied then resend the whole thing so people don't
have to work out which versions of which patches are the current ones.


signature.asc
Description: PGP signature


Re: [PATCH v2 2/3] spi: add FTDI MPSSE SPI controller driver

2018-11-13 Thread Anatolij Gustschin
On Tue, 13 Nov 2018 10:11:32 -0800
Mark Brown broo...@kernel.org wrote:

>Please don't do this, the numbering for a patch series only makes sense
>for ordering the patches within a series.  If you're just sending a
>single patch then there's no need to number anything, or the patch
>series hasn't been applied then resend the whole thing so people don't
>have to work out which versions of which patches are the current ones.

got it, thanks.

Anatolij


Re: [PATCH] Improve the accuracy of the baud rate generator by using round-to-closest instead of truncating when calculating baud rate divisors.

2018-11-13 Thread Nikolaj Fogh




On 11/12/18 10:54 AM, Johan Hovold wrote:

On Wed, Oct 31, 2018 at 09:16:48PM +0100, Nikolaj Fogh wrote:

I have experienced that the ftdi_sio driver gives less-than-optimal baud rates 
as the driver truncates instead of rounds to nearest during baud rate divisor 
calculation.

Please break your lines at 72 cols or so, and use the common subject
prefix (e.g. "USB: serial: ftdi_sio: improve...") with a concise
summary.

Ok. I will do that in the future.

This patch improves on the baud rate generation. The generated baud rate 
corresponds to the optimal baud rate achievable with the chip. This is what the 
windows driver gives as well.

How did you verify this? Did you trace and compare the divisors
actually requested by the Windows driver, or did you measure the
resulting rates using a scope?

Thanks,
Johan

I verified it by scope. Granted, I only verified it for one baud rate
(961200). Whether it gives the same as the Windows driver in general,
I'm not sure. However, I would think that rounding instead of flooring
would always yield the most accurate result.

Best regards
  Nikolaj Fogh


Re: [PATCH 4/4] arm64: dts: exynos: Update DWC3 modules on Exynos5433 SoCs

2018-11-13 Thread Krzysztof Kozlowski
On Tue, Sep 18, 2018 at 10:16:53AM +0200, Marek Szyprowski wrote:
> Update DWC3 hardware modules to Exynos5433 specific variant: change
> compatible name and add all required clocks (both to the glue node and
> DWC3 core node).
> 
> Signed-off-by: Marek Szyprowski 
> ---
>  arch/arm64/boot/dts/exynos/exynos5433.dtsi | 24 --

Thanks, applied.

Best regards,
Krzysztof



Re: [PATCH 0/2] USB: serial: gpio line-name fix and FT232R CBUS gpio support

2018-11-13 Thread Johan Hovold
Hi Linus,

Sorry about the late reply, this one got buried in the mailbox during
conference travels.

On Wed, Oct 10, 2018 at 11:36:28AM +0200, Linus Walleij wrote:
> On Fri, Oct 5, 2018 at 3:40 PM Johan Hovold  wrote:
> > On Mon, Oct 01, 2018 at 11:43:55AM +0200, Linus Walleij wrote:
> 
> > > The idea is to make it possible for userspace to look up a GPIO
> > > on a chip by name, so if the gpiochip has a unique name,
> > > and the line name is unique on that chip it should be good
> > > enough.
> >
> > I haven't really had time do dig into this again, but is this also an
> > issue with the chardev interface?
> >
> > I thought this was one of the things
> > you wanted to get right with the new interface, so hopefully that's
> > already taken care of.
> 
> It is always possible to use /dev/gpiochipN and offet M on
> that gpiochip to pick a unique line. That is a unique offset
> on a unique chip. The gpiochip also has a "label" which may
> be something user-readable such as part numer, but the unique
> string is its name such as "gpiochip0".

Right.

> For symbolic look-up though, like a file has to have a unique
> path, the name of the line should be unique.

Sure, but there's no way to guarantee that (consider pluggable devices)
unless you encode the topology in the name.

> It is allowed to have unnamed lines though, so it is only a
> hint. While I would like all drivers to uniquely name their
> lines in DT or ACPI, or using the .names array in the gpio_chip
> struct, it cannot be enforced because of legacy support,
> so many old systems had no names specified, and
> the DT and ACPI properties to name lines were introduced
> after the chardev actually.

Oh, that's right.

> All I enforce is that if names are added, they should be
> unique.

Which effectively means you cannot have a driver provide default line
names, as that would cause conflicts if there are ever more than one
such device in a system (be it i2c or pluggable USB).

> What we *could* do is conjure a unique name per line if
> the hardware description doesn't provice one... like
> "line0", "line1", "line2"... "lineN" on the chip.
> 
> Should we add a patch like that? The only side effect
> I can see if that maybe the footprint increase is not so
> nice.
> 
> I had it in mind but it slipped of my radar. It would make
> all lines always have unique names.

No, I don't think that's needed or desirable.

But take the concrete use case at hand; a gpio controller connected over
USB. These FTDI devices exposes four gpios on a set of pins that differ
from model to model. On some devices these lines are available on a set
of pins named CBUS0..CBUS3, on others a different set of pins such as
ACBUS5, ACBUS6, ACBUS8 and ACBUS9 are used.

Exporting which line is exposed on which pin obviously has some worth,
but this is currently not possible due to the requirement that line
names must be unique.

Having an interface that allows you to look up say ACBUS6 given a
particular gpiochip would also be useful to have (user space knows which
USB device it is interested in so finding the gpiochip is straight
forward).

Perhaps the chardev interface could return a set of matched gpiochips if
a particular line name is found on several chips for user space to
iterate over.

Essentially what I'm going for is to have the line names only be
required to be unique per chip, and let user space deal with any
collisions.

The flat line name space really only works for something like DT, and
then only if you actually have access to the DTS (I'm assuming there's
no uniqueness requirement in the binding docs?).

But you could still run into trouble if an i2c driver provides default
names, or if you use anything pluggable.

> > If the flat name space is only an issue with the legacy interface we
> > might get away with simply not using the line names in sysfs when a new
> > chip flag is set (unless we can resue .can_sleep, but there seems to be
> > some i2c devices already using line names).
> 
> Hm. So you mean it is bad that the exporting GPIOs in the old
> sysfs brings out the line name in sysfs if the line is named.

Right, this specifically prevents using line names with pluggable
devices.

> I just want the sysfs to die, but yeah what you say makes
> sense. I don't know if it's such a big issue, my focus has been
> on making the chardev more appetizing and the sysfs
> uncomfortably oldschool amongst users. This would make it
> even more uncomfortable.
> 
> But I don't know if the old sysfs users actually use the line
> names much?

The problem is that the line names are used in sysfs as device names
(file names) instead of "gpioN" whenever a line name has been specified.
So on systems with line names defined, we would definitely risk
regressions if we simply stopped exporting gpios using those names.

Doing so for a subset of devices (e.g. i2c, or anything connected over a
slow bus) may still be considered though. That would also deal with the
USB case.

But again, I'm not

Re: USB-C device hotplug issue

2018-11-13 Thread Dennis Wassenberg
On 09.11.18 14:47, Mathias Nyman wrote:
> On 07.11.2018 11:08, Dennis Wassenberg wrote:
>>
>> On 05.11.18 16:35, Mathias Nyman wrote:
>>> On 26.10.2018 17:07, Alan Stern wrote:
 On Fri, 26 Oct 2018, Dennis Wassenberg wrote:

>>> --- a/drivers/usb/core/hub.c
>>> +++ b/drivers/usb/core/hub.c
>>> @@ -2815,7 +2815,9 @@ static int hub_port_reset(struct usb_hub *hub, 
>>> int port1,
>>>    USB_PORT_FEAT_C_BH_PORT_RESET);
>>>    usb_clear_port_feature(hub->hdev, port1,
>>>    USB_PORT_FEAT_C_PORT_LINK_STATE);
>>> -    usb_clear_port_feature(hub->hdev, port1,
>>> +
>>> +    if (!warm)
>>> +    usb_clear_port_feature(hub->hdev, port1,
>>>    USB_PORT_FEAT_C_CONNECTION);
>>>      /*
>>
>> The key fact is that connection events can get lost if they happen to
>> occur during a port reset.
> Yes.
>>
>> I'm not entirely certain of the logic here, but it looks like the
>> correct test to add should be "if (udev != NULL)", not "if (!warm)".
>> Perhaps Mathias can confirm this
>>>
>>> Sorry about the late response, got distracted while performing git
>>> archeology.
>>>
>>> "if (udev != NULL)" would seem more reasonable.
>>>
>>> Logs show that clearing the FEAT_C_CONNECTION was originally added
>>> after a hot reset failed, and before issuing a warm reset to a SS.Inactive
>>> link.  (see 10d674a USB: When hot reset for USB3 fails, try warm reset.)
>>>
>>> Apparently all the change flags needed to be cleared for some specific
>>> host + device combination before issuing a warm reset for the enumeration
>>> to work properly.
>>>
>>> The change to always clear FEAT_C_CONNECTION for USB3 was done later in 
>>> patch:
>>> a24a607 USB: Rip out recursive call on warm port reset.
>>>
>>> Motivation was:
>>>
>>> "In hub_port_finish_reset, unconditionally clear the connect status
>>>   change (CSC) bit for USB 3.0 hubs when the port reset is done.  If we
>>>   had to issue multiple warm resets for a device, that bit may have been
>>>   set if the device went into SS.Inactive and then was successfully warm
>>>   reset."
>>>
> I don't know if clearing the USB_PORT_FEAT_C_CONNECTION bit is
> correct in case of a non warm reset. In my case I always observed a
> warm reset because of the link state change.
> Thats why I checked the warm variable to not change the behavoir for
> cases a didn't checked for the first shot.

 (The syntax of that last sentence is pretty mangled; I can't understand
 it.)

 Think of it this way:

  If a device was not attached before the reset, we don't want
  to clear the connect-change status because then we wouldn't
  recognize a device that was plugged in during the reset.

  If a device was attached before the reset, we don't want any
  connect-change status which might be provoked by the reset to
  last, because we don't want the core to think that the device
  was unplugged and replugged when all that happened was a reset.

 So the important criterion is whether or not a device was attached to
 the port when the reset started.  It's something of a coincidence that
 you only observe warm resets when there's nothing attached.

> During the first run of usb_hub_reset the udev is NULL because in
> this situation the device is not attached logically.
>
> [  112.889810] usb 4-1-port1: XXX: port_event: portstatus: 0x2c0, 
> portchange: 0x40!
> [  113.201192] usb 4-1-port1: XXX: hub_port_reset: udev:    (nil)!
> [  113.201198] usb 4-1-port1: XXX: hub_port_reset (not clearing 
> USB_PORT_FEAT_C_CONNECTION): 0x203, portchange: 0x1!
> [  113.253612] usb 4-1-port1: XXX: port_event: portstatus: 0x203, 
> portchange: 0x1!
> [  113.377208] usb 4-1-port1: XXX: hub_port_reset: udev: 88046b302800!
> [  113.377214] usb 4-1-port1: XXX: hub_port_reset (not clearing 
> USB_PORT_FEAT_C_CONNECTION): 0x203, portchange: 0x0!
> [  113.429478] usb 4-1.1: new SuperSpeed USB device number 7 using 
> xhci_hcd
> [  113.442370] usb 4-1.1: New USB device found, idVendor=0781, 
> idProduct=5596
> [  113.442376] usb 4-1.1: New USB device strings: Mfr=1, Product=2, 
> SerialNumber=3
> [  113.442381] usb 4-1.1: Product: Ultra T C
> [  113.442385] usb 4-1.1: Manufacturer: SanDisk
> [  113.442388] usb 4-1.1: SerialNumber: 4C530001131013121031
>
> Or maybe we can skip clearing the USB_PORT_FEAT_C_CONNECTION bit in
> case of hub_port_reset completely without any other check?

 See above.
>>>
>>> Checking for udev sounds reasonable to me.
>>> Not sure if we should worry about the specific host+device combo that 
>>> needed flags
>>> cleared before warm reset. See patch:
>>>
>>> 10d674a USB: When hot reset f

[PATCH] usb: core: Fix hub port connection events lost

2018-11-13 Thread Dennis Wassenberg
This will clear the USB_PORT_FEAT_C_CONNECTION bit in case of a hub port reset
only if a device is was attached to the hub port before resetting the hub port.

Using a Lenovo T480s attached to the ultra dock it was not possible to detect
some usb-c devices at the dock usb-c ports because the hub_port_reset code
will clear the USB_PORT_FEAT_C_CONNECTION bit after the actual hub port reset.
Using this device combo the USB_PORT_FEAT_C_CONNECTION bit was set between the
actual hub port reset and the clear of the USB_PORT_FEAT_C_CONNECTION bit.
This ends up with clearing the USB_PORT_FEAT_C_CONNECTION bit after the
new device was attached such that it was not detected.

This patch will not clear the USB_PORT_FEAT_C_CONNECTION bit if there is
currently no device attached to the port before the hub port reset.
This will avoid clearing the connection bit for new attached devices.

Signed-off-by: Dennis Wassenberg 
---
 drivers/usb/core/hub.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index c6077d582d29..2731fad6f659 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2849,7 +2849,9 @@ static int hub_port_reset(struct usb_hub *hub, int port1,
USB_PORT_FEAT_C_BH_PORT_RESET);
usb_clear_port_feature(hub->hdev, port1,
USB_PORT_FEAT_C_PORT_LINK_STATE);
-   usb_clear_port_feature(hub->hdev, port1,
+
+   if (udev)
+   usb_clear_port_feature(hub->hdev, port1,
USB_PORT_FEAT_C_CONNECTION);
 
/*
-- 
2.17.1



Re: [PATCH] usb: core: Fix hub port connection events lost

2018-11-13 Thread Mathias Nyman

On 13.11.2018 15:40, Dennis Wassenberg wrote:

This will clear the USB_PORT_FEAT_C_CONNECTION bit in case of a hub port reset
only if a device is was attached to the hub port before resetting the hub port.

Using a Lenovo T480s attached to the ultra dock it was not possible to detect
some usb-c devices at the dock usb-c ports because the hub_port_reset code
will clear the USB_PORT_FEAT_C_CONNECTION bit after the actual hub port reset.
Using this device combo the USB_PORT_FEAT_C_CONNECTION bit was set between the
actual hub port reset and the clear of the USB_PORT_FEAT_C_CONNECTION bit.
This ends up with clearing the USB_PORT_FEAT_C_CONNECTION bit after the
new device was attached such that it was not detected.

This patch will not clear the USB_PORT_FEAT_C_CONNECTION bit if there is
currently no device attached to the port before the hub port reset.
This will avoid clearing the connection bit for new attached devices.

Signed-off-by: Dennis Wassenberg 
---
  drivers/usb/core/hub.c | 4 +++-
  1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index c6077d582d29..2731fad6f659 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2849,7 +2849,9 @@ static int hub_port_reset(struct usb_hub *hub, int port1,
USB_PORT_FEAT_C_BH_PORT_RESET);
usb_clear_port_feature(hub->hdev, port1,
USB_PORT_FEAT_C_PORT_LINK_STATE);
-   usb_clear_port_feature(hub->hdev, port1,
+
+   if (udev)
+   usb_clear_port_feature(hub->hdev, port1,
USB_PORT_FEAT_C_CONNECTION);
  
  			/*




Acked-by: Mathias Nyman 


[PATCH v2 net-next 02/21] net: usb: aqc111: Add bind and empty unbind callbacks

2018-11-13 Thread Igor Russkikh
From: Dmitry Bezrukov 

Initialize net_device_ops structure

Signed-off-by: Dmitry Bezrukov 
Signed-off-by: Igor Russkikh 
---
 drivers/net/usb/aqc111.c | 35 +++
 1 file changed, 35 insertions(+)

diff --git a/drivers/net/usb/aqc111.c b/drivers/net/usb/aqc111.c
index aaea2a4fcc9f..b54bb4a98ee3 100644
--- a/drivers/net/usb/aqc111.c
+++ b/drivers/net/usb/aqc111.c
@@ -14,8 +14,43 @@
 #include 
 #include 
 
+static const struct net_device_ops aqc111_netdev_ops = {
+   .ndo_open   = usbnet_open,
+   .ndo_stop   = usbnet_stop,
+};
+
+static int aqc111_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+   struct usb_device *udev = interface_to_usbdev(intf);
+   int ret;
+
+   /* Check if vendor configuration */
+   if (udev->actconfig->desc.bConfigurationValue != 1) {
+   usb_driver_set_configuration(udev, 1);
+   return -ENODEV;
+   }
+
+   usb_reset_configuration(dev->udev);
+
+   ret = usbnet_get_endpoints(dev, intf);
+   if (ret < 0) {
+   netdev_dbg(dev->net, "usbnet_get_endpoints failed");
+   return ret;
+   }
+
+   dev->net->netdev_ops = &aqc111_netdev_ops;
+
+   return 0;
+}
+
+static void aqc111_unbind(struct usbnet *dev, struct usb_interface *intf)
+{
+}
+
 static const struct driver_info aqc111_info = {
.description= "Aquantia AQtion USB to 5GbE Controller",
+   .bind   = aqc111_bind,
+   .unbind = aqc111_unbind,
 };
 
 #define AQC111_USB_ETH_DEV(vid, pid, table) \
-- 
2.7.4



[PATCH v2 net-next 00/21] Add support for Aquantia AQtion USB to 5/2.5GbE devices

2018-11-13 Thread Igor Russkikh
This patchset introduces support for new multigig ethernet to USB dongle,
developed jointly by Aquantia (Phy) and ASIX (USB MAC).

The driver has similar structure with other ASIX MAC drivers (AX88179), but
with a number of important differences:
- Driver supports both direct Phy and custom firmware interface for Phy
  programming. This is due to different firmware modules available with
  this product.
- Driver handles new 2.5G/5G link speed configuration and reporting.
- Device support all speeds from 100M up to 5G.
- Device supports MTU up to 16K.

Device supports various standard networking features, like
checksum offloads, vlan tagging/filtering, TSO.

The code of this driver is based on original ASIX sources and was extended
by Aquantia for 5G multigig support.

Patchset v2 includes following changes:
- Function variables declarions fixed to reverse xmass tree
- Improve patch layout structure
- Remove unnecessary curly braces in switch/case statements
- Use 'packed' attribute for HW structures only
- Use eth_mac_addr function in set_mac_addr callback
- Remove unnecessary 'memset' calls.
- Read MAC address from EEPROM function has now better name
- Use driver_priv field to store context. It avoids ugly cast.
- Set max_mtu field. Remove check for MTU size
- Rewrite read/write functions. Add helpers for read/write 16/32 bit values
- Use mask and shifts instead of bitfields to support BE platforms.
- Use stack allocated buffer for configuring mcast filters
- Use AUTONEG_ENABLE when go to suspend state
- Pad out wol_cfg field from context structure. Use stack allocated instead
- Remove driver version
- Check field 'duplex' in set_link_ksetting callback as well
- Use already created defines in usb matching macro
- Rename phy_ops struct to phy_cfg
- Use ether_addr_copy for copying mac address
- Add fall-through comment in switch/case for avoid checkpatch warning
- Remove match for CDC ether device
- Add ASIX's HW id-s to match this driver
- Add all HW id-s with which driver can work to blacklist of cdc_ether driver

Dmitry Bezrukov (21):
  net: usb: aqc111: Driver skeleton for Aquantia AQtion USB to 5GbE
  net: usb: aqc111: Add bind and empty unbind callbacks
  net: usb: aqc111: Add implementation of read and write commands
  net: usb: aqc111: Various callbacks implementation
  net: usb: aqc111: Introduce PHY access
  net: usb: aqc111: Introduce link management
  net: usb: aqc111: Add support for getting and setting of MAC address
  net: usb: aqc111: Implement TX data path
  net: usb: aqc111: Implement RX data path
  net: usb: aqc111: Add checksum offload support
  net: usb: aqc111: Add support for changing MTU
  net: usb: aqc111: Add support for enable/disable checksum offload
  net: usb: aqc111: Add support for TSO
  net: usb: aqc111: Implement set_rx_mode callback
  net: usb: aqc111: Add support for VLAN_CTAG_TX/RX offload
  net: usb: aqc111: Add RX VLAN filtering support
  net: usb: aqc111: Initialize ethtool_ops structure
  net: usb: aqc111: Implement get/set_link_ksettings callbacks
  net: usb: aqc111: Add support for wake on LAN by MAGIC packet
  net: usb: aqc111: Add ASIX's HW ids
  net: usb: aqc111: Extend cdc_ether blacklist

 drivers/net/usb/Kconfig |   12 +
 drivers/net/usb/Makefile|1 +
 drivers/net/usb/aqc111.c| 1605 +++
 drivers/net/usb/aqc111.h|  275 
 drivers/net/usb/cdc_ether.c |   23 +
 5 files changed, 1916 insertions(+)
 create mode 100644 drivers/net/usb/aqc111.c
 create mode 100644 drivers/net/usb/aqc111.h

-- 
2.7.4



[PATCH v2 net-next 03/21] net: usb: aqc111: Add implementation of read and write commands

2018-11-13 Thread Igor Russkikh
From: Dmitry Bezrukov 

Read/write command register defines and functions

Signed-off-by: Dmitry Bezrukov 
Signed-off-by: Igor Russkikh 
---
 drivers/net/usb/aqc111.c | 92 
 drivers/net/usb/aqc111.h | 18 ++
 2 files changed, 110 insertions(+)
 create mode 100644 drivers/net/usb/aqc111.h

diff --git a/drivers/net/usb/aqc111.c b/drivers/net/usb/aqc111.c
index b54bb4a98ee3..34ed841b81dc 100644
--- a/drivers/net/usb/aqc111.c
+++ b/drivers/net/usb/aqc111.c
@@ -14,6 +14,98 @@
 #include 
 #include 
 
+#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
index ..f4302f7f0cc3
--- /dev/null
+++ b/drivers/net/usb/aqc111.h
@@ -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 
+ * Copyright (C) 2005 Phil Chang 
+ * 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 1
+#define AQ_USB_SET_TIMEOUT 4000
+
+#endif /* __LINUX_USBNET_AQC111_H */
-- 
2.7.4



[PATCH v2 net-next 01/21] net: usb: aqc111: Driver skeleton for Aquantia AQtion USB to 5GbE

2018-11-13 Thread Igor Russkikh
From: Dmitry Bezrukov 

Initialize usb_driver structure skeleton

Signed-off-by: Dmitry Bezrukov 
Signed-off-by: Igor Russkikh 
---
 drivers/net/usb/Kconfig  | 12 
 drivers/net/usb/Makefile |  1 +
 drivers/net/usb/aqc111.c | 41 +
 3 files changed, 54 insertions(+)
 create mode 100644 drivers/net/usb/aqc111.c

diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
index 418b0904cecb..e5fb8ef2d815 100644
--- a/drivers/net/usb/Kconfig
+++ b/drivers/net/usb/Kconfig
@@ -613,4 +613,16 @@ config USB_NET_CH9200
  To compile this driver as a module, choose M here: the
  module will be called ch9200.
 
+config USB_NET_AQC111
+   tristate "Aquantia AQtion USB to 5/2.5GbE Controllers support"
+   depends on USB_USBNET
+   select CRC32
+   default y
+   help
+ This option adds support for Aquantia AQtion USB
+ Ethernet adapters based on AQC111U/AQC112 chips.
+
+ This driver should work with at least the following devices:
+ * Aquantia AQtion USB to 5GbE
+
 endif # USB_NET_DRIVERS
diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile
index 27307a4ab003..99fd12be2111 100644
--- a/drivers/net/usb/Makefile
+++ b/drivers/net/usb/Makefile
@@ -40,3 +40,4 @@ obj-$(CONFIG_USB_VL600)   += lg-vl600.o
 obj-$(CONFIG_USB_NET_QMI_WWAN) += qmi_wwan.o
 obj-$(CONFIG_USB_NET_CDC_MBIM) += cdc_mbim.o
 obj-$(CONFIG_USB_NET_CH9200)   += ch9200.o
+obj-$(CONFIG_USB_NET_AQC111)   += aqc111.o
diff --git a/drivers/net/usb/aqc111.c b/drivers/net/usb/aqc111.c
new file mode 100644
index ..aaea2a4fcc9f
--- /dev/null
+++ b/drivers/net/usb/aqc111.c
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/* Aquantia Corp. Aquantia AQtion USB to 5GbE Controller
+ * Copyright (C) 2003-2005 David Hollis 
+ * Copyright (C) 2005 Phil Chang 
+ * Copyright (C) 2002-2003 TiVo Inc.
+ * Copyright (C) 2017-2018 ASIX
+ * Copyright (C) 2018 Aquantia Corp.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static const struct driver_info aqc111_info = {
+   .description= "Aquantia AQtion USB to 5GbE Controller",
+};
+
+#define AQC111_USB_ETH_DEV(vid, pid, table) \
+   USB_DEVICE_INTERFACE_CLASS((vid), (pid), USB_CLASS_VENDOR_SPEC), \
+   .driver_info = (unsigned long)&(table)
+
+static const struct usb_device_id products[] = {
+   {AQC111_USB_ETH_DEV(0x2eca, 0xc101, aqc111_info)},
+   { },/* END */
+};
+MODULE_DEVICE_TABLE(usb, products);
+
+static struct usb_driver aq_driver = {
+   .name   = "aqc111",
+   .id_table   = products,
+   .probe  = usbnet_probe,
+   .disconnect = usbnet_disconnect,
+};
+
+module_usb_driver(aq_driver);
+
+MODULE_DESCRIPTION("Aquantia AQtion USB to 5/2.5GbE Controllers");
+MODULE_LICENSE("GPL");
-- 
2.7.4



[PATCH v2 net-next 09/21] net: usb: aqc111: Implement RX data path

2018-11-13 Thread Igor Russkikh
From: Dmitry Bezrukov 

Signed-off-by: Dmitry Bezrukov 
Signed-off-by: Igor Russkikh 
---
 drivers/net/usb/aqc111.c | 103 +++
 drivers/net/usb/aqc111.h |  15 +++
 2 files changed, 118 insertions(+)

diff --git a/drivers/net/usb/aqc111.c b/drivers/net/usb/aqc111.c
index b630a8342ef2..ae101b44a109 100644
--- a/drivers/net/usb/aqc111.c
+++ b/drivers/net/usb/aqc111.c
@@ -376,6 +376,9 @@ static int aqc111_bind(struct usbnet *dev, struct 
usb_interface *intf)
 
ether_addr_copy(dev->net->dev_addr, dev->net->perm_addr);
 
+   /* Set Rx urb size */
+   dev->rx_urb_size = URB_SIZE;
+
/* Set TX needed headroom & tailroom */
dev->net->needed_headroom += sizeof(u64);
dev->net->needed_tailroom += sizeof(u64);
@@ -617,6 +620,8 @@ static int aqc111_reset(struct usbnet *dev)
u16 reg16 = 0;
u8 reg8 = 0;
 
+   dev->rx_urb_size = URB_SIZE;
+
if (usb_device_no_sg_constraint(dev->udev))
dev->can_dma_sg = 1;
 
@@ -699,6 +704,103 @@ static int aqc111_stop(struct usbnet *dev)
return 0;
 }
 
+static int aqc111_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+{
+   struct sk_buff *new_skb = NULL;
+   u32 pkt_total_offset = 0;
+   u32 start_of_descs = 0;
+   u64 *pkt_desc = NULL;
+   u32 desc_offset = 0; /*RX Header Offset*/
+   u16 pkt_count = 0;
+   u64 desc_hdr = 0;
+   u32 skb_len = 0;
+
+   if (!skb)
+   goto err;
+
+   if (skb->len == 0)
+   goto err;
+
+   skb_len = skb->len;
+   /* RX Descriptor Header */
+   skb_trim(skb, skb->len - sizeof(desc_hdr));
+   desc_hdr = *(u64 *)skb_tail_pointer(skb);
+   le64_to_cpus(&desc_hdr);
+
+   /* Check these packets */
+   desc_offset = (desc_hdr & AQ_RX_DH_DESC_OFFSET_MASK) >>
+ AQ_RX_DH_DESC_OFFSET_SHIFT;
+   pkt_count = desc_hdr & AQ_RX_DH_PKT_CNT_MASK;
+   start_of_descs = skb_len - ((pkt_count + 1) *  sizeof(desc_hdr));
+
+   /* self check descs position */
+   if (start_of_descs != desc_offset)
+   goto err;
+
+   /* self check desc_offset from header*/
+   if (desc_offset >= skb_len)
+   goto err;
+
+   if (pkt_count == 0)
+   goto err;
+
+   /* Get the first RX packet descriptor */
+   pkt_desc = (u64 *)(skb->data + desc_offset);
+
+   while (pkt_count--) {
+   u32 pkt_len = 0;
+   u32 pkt_len_with_padd = 0;
+
+   le64_to_cpus(pkt_desc);
+   pkt_len = (u32)((*pkt_desc & AQ_RX_PD_LEN_MASK) >>
+ AQ_RX_PD_LEN_SHIFT);
+   pkt_len_with_padd = ((pkt_len + 7) & 0x7FFF8);
+
+   pkt_total_offset += pkt_len_with_padd;
+   if (pkt_total_offset > desc_offset ||
+   (pkt_count == 0 && pkt_total_offset != desc_offset)) {
+   goto err;
+   }
+
+   if (*pkt_desc & AQ_RX_PD_DROP ||
+   !(*pkt_desc & AQ_RX_PD_RX_OK) ||
+   pkt_len > (dev->hard_mtu + AQ_RX_HW_PAD)) {
+   skb_pull(skb, pkt_len_with_padd);
+   /* Next RX Packet Descriptor */
+   pkt_desc++;
+   continue;
+   }
+
+   /* Clone SKB */
+   new_skb = skb_clone(skb, GFP_ATOMIC);
+
+   if (!new_skb)
+   goto err;
+
+   new_skb->len = pkt_len;
+   skb_pull(new_skb, AQ_RX_HW_PAD);
+   skb_set_tail_pointer(new_skb, new_skb->len);
+
+   new_skb->truesize = new_skb->len + sizeof(struct sk_buff);
+
+   usbnet_skb_return(dev, new_skb);
+   if (pkt_count == 0)
+   break;
+
+   skb_pull(skb, pkt_len_with_padd);
+
+   /* Next RX Packet Header */
+   pkt_desc++;
+
+   new_skb = NULL;
+   }
+
+   return 1;
+
+err:
+   return 0;
+}
+
 static struct sk_buff *aqc111_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
   gfp_t flags)
 {
@@ -758,6 +860,7 @@ static const struct driver_info aqc111_info = {
.stop   = aqc111_stop,
.flags  = FLAG_ETHER | FLAG_FRAMING_AX |
  FLAG_AVOID_UNLINK_URBS | FLAG_MULTI_PACKET,
+   .rx_fixup   = aqc111_rx_fixup,
.tx_fixup   = aqc111_tx_fixup,
 };
 
diff --git a/drivers/net/usb/aqc111.h b/drivers/net/usb/aqc111.h
index a3d9d7dde240..aa0b37ebabae 100644
--- a/drivers/net/usb/aqc111.h
+++ b/drivers/net/usb/aqc111.h
@@ -10,6 +10,8 @@
 #ifndef __LINUX_USBNET_AQC111_H
 #define __LINUX_USBNET_AQC111_H
 
+#define URB_SIZE   (1024 * 62)
+
 #define AQ_ACCESS_MAC  0x01
 #define AQ_FLASH_PARAMETERS0x20
 #define AQ_PHY_POWER   0x31
@@ -200,6 +202,19 @@ struct aqc111_

[PATCH v2 net-next 10/21] net: usb: aqc111: Add checksum offload support

2018-11-13 Thread Igor Russkikh
From: Dmitry Bezrukov 

Signed-off-by: Dmitry Bezrukov 
Signed-off-by: Igor Russkikh 
---
 drivers/net/usb/aqc111.c | 38 ++
 drivers/net/usb/aqc111.h | 16 ++--
 2 files changed, 52 insertions(+), 2 deletions(-)

diff --git a/drivers/net/usb/aqc111.c b/drivers/net/usb/aqc111.c
index ae101b44a109..90061157b7ac 100644
--- a/drivers/net/usb/aqc111.c
+++ b/drivers/net/usb/aqc111.c
@@ -536,6 +536,26 @@ static void aqc111_configure_rx(struct usbnet *dev,
netdev_info(dev->net, "Link Speed %d, USB %d", link_speed, usb_host);
 }
 
+static void aqc111_configure_csum_offload(struct usbnet *dev)
+{
+   u8 reg8 = 0;
+
+   if (dev->net->features & NETIF_F_RXCSUM) {
+   reg8 |= SFR_RXCOE_IP | SFR_RXCOE_TCP | SFR_RXCOE_UDP |
+   SFR_RXCOE_TCPV6 | SFR_RXCOE_UDPV6;
+   }
+   aqc111_write_cmd(dev, AQ_ACCESS_MAC, SFR_RXCOE_CTL, 1, 1, ®8);
+
+   reg8 = 0;
+   if (dev->net->features & NETIF_F_IP_CSUM)
+   reg8 |= SFR_TXCOE_IP | SFR_TXCOE_TCP | SFR_TXCOE_UDP;
+
+   if (dev->net->features & NETIF_F_IPV6_CSUM)
+   reg8 |= SFR_TXCOE_TCPV6 | SFR_TXCOE_UDPV6;
+
+   aqc111_write_cmd(dev, AQ_ACCESS_MAC, SFR_TXCOE_CTL, 1, 1, ®8);
+}
+
 static int aqc111_link_reset(struct usbnet *dev)
 {
struct aqc111_data *aqc111_data = dev->driver_priv;
@@ -579,6 +599,8 @@ static int aqc111_link_reset(struct usbnet *dev)
aqc111_write16_cmd(dev, AQ_ACCESS_MAC, SFR_MEDIUM_STATUS_MODE,
   2, ®16);
 
+   aqc111_configure_csum_offload(dev);
+
aqc111_read16_cmd(dev, AQ_ACCESS_MAC, SFR_MEDIUM_STATUS_MODE,
  2, ®16);
 
@@ -704,6 +726,21 @@ static int aqc111_stop(struct usbnet *dev)
return 0;
 }
 
+static void aqc111_rx_checksum(struct sk_buff *skb, u64 *pkt_desc)
+{
+   u32 pkt_type = 0;
+
+   skb->ip_summed = CHECKSUM_NONE;
+   /* checksum error bit is set */
+   if (*pkt_desc & AQ_RX_PD_L4_ERR || *pkt_desc & AQ_RX_PD_L3_ERR)
+   return;
+
+   pkt_type = *pkt_desc & AQ_RX_PD_L4_TYPE_MASK;
+   /* It must be a TCP or UDP packet with a valid checksum */
+   if (pkt_type == AQ_RX_PD_L4_TCP || pkt_type == AQ_RX_PD_L4_UDP)
+   skb->ip_summed = CHECKSUM_UNNECESSARY;
+}
+
 static int aqc111_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
 {
struct sk_buff *new_skb = NULL;
@@ -782,6 +819,7 @@ static int aqc111_rx_fixup(struct usbnet *dev, struct 
sk_buff *skb)
skb_set_tail_pointer(new_skb, new_skb->len);
 
new_skb->truesize = new_skb->len + sizeof(struct sk_buff);
+   aqc111_rx_checksum(new_skb, pkt_desc);
 
usbnet_skb_return(dev, new_skb);
if (pkt_count == 0)
diff --git a/drivers/net/usb/aqc111.h b/drivers/net/usb/aqc111.h
index aa0b37ebabae..20637fd58be3 100644
--- a/drivers/net/usb/aqc111.h
+++ b/drivers/net/usb/aqc111.h
@@ -63,8 +63,11 @@
 #define AQ_USB_SET_TIMEOUT 4000
 
 /* Feature. /
-#define AQ_SUPPORT_FEATURE (NETIF_F_SG)
-#define AQ_SUPPORT_HW_FEATURE  (NETIF_F_SG)
+#define AQ_SUPPORT_FEATURE (NETIF_F_SG | NETIF_F_IP_CSUM |\
+NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM)
+
+#define AQ_SUPPORT_HW_FEATURE  (NETIF_F_SG | NETIF_F_IP_CSUM |\
+NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM)
 
 /* SFR Reg. /
 
@@ -205,6 +208,15 @@ struct aqc111_data {
 #define AQ_RX_HW_PAD   0x02
 
 /* RX Packet Descriptor */
+#define AQ_RX_PD_L4_ERRBIT(0)
+#define AQ_RX_PD_L3_ERRBIT(1)
+#define AQ_RX_PD_L4_TYPE_MASK  0x1C
+#define AQ_RX_PD_L4_UDP0x04
+#define AQ_RX_PD_L4_TCP0x10
+#define AQ_RX_PD_L3_TYPE_MASK  0x60
+#define AQ_RX_PD_L3_IP 0x20
+#define AQ_RX_PD_L3_IP60x40
+
 #define AQ_RX_PD_RX_OK BIT(11)
 #define AQ_RX_PD_DROP  BIT(31)
 #define AQ_RX_PD_LEN_MASK  0x7FFF
-- 
2.7.4



[PATCH v2 net-next 13/21] net: usb: aqc111: Add support for TSO

2018-11-13 Thread Igor Russkikh
From: Dmitry Bezrukov 

Signed-off-by: Dmitry Bezrukov 
Signed-off-by: Igor Russkikh 
---
 drivers/net/usb/aqc111.c | 4 
 drivers/net/usb/aqc111.h | 8 ++--
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/net/usb/aqc111.c b/drivers/net/usb/aqc111.c
index 891d6832b87c..2cbdca3d8dfc 100644
--- a/drivers/net/usb/aqc111.c
+++ b/drivers/net/usb/aqc111.c
@@ -953,6 +953,10 @@ static struct sk_buff *aqc111_tx_fixup(struct usbnet *dev, 
struct sk_buff *skb,
/*Length of actual data*/
tx_desc |= skb->len & AQ_TX_DESC_LEN_MASK;
 
+   /* TSO MSS */
+   tx_desc |= ((u64)(skb_shinfo(skb)->gso_size & AQ_TX_DESC_MSS_MASK)) <<
+  AQ_TX_DESC_MSS_SHIFT;
+
headroom = (skb->len + sizeof(tx_desc)) % 8;
if (headroom != 0)
padding_size = 8 - headroom;
diff --git a/drivers/net/usb/aqc111.h b/drivers/net/usb/aqc111.h
index 477815f8b7de..b27c4db22a51 100644
--- a/drivers/net/usb/aqc111.h
+++ b/drivers/net/usb/aqc111.h
@@ -64,10 +64,12 @@
 
 /* Feature. /
 #define AQ_SUPPORT_FEATURE (NETIF_F_SG | NETIF_F_IP_CSUM |\
-NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM)
+NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM |\
+NETIF_F_TSO)
 
 #define AQ_SUPPORT_HW_FEATURE  (NETIF_F_SG | NETIF_F_IP_CSUM |\
-NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM)
+NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM |\
+NETIF_F_TSO)
 
 /* SFR Reg. /
 
@@ -205,6 +207,8 @@ struct aqc111_data {
 /* TX Descriptor */
 #define AQ_TX_DESC_LEN_MASK0x1F
 #define AQ_TX_DESC_DROP_PADD   BIT(28)
+#define AQ_TX_DESC_MSS_MASK0x7FFF
+#define AQ_TX_DESC_MSS_SHIFT   0x20
 
 #define AQ_RX_HW_PAD   0x02
 
-- 
2.7.4



[PATCH v2 net-next 11/21] net: usb: aqc111: Add support for changing MTU

2018-11-13 Thread Igor Russkikh
From: Dmitry Bezrukov 

Signed-off-by: Dmitry Bezrukov 
Signed-off-by: Igor Russkikh 
---
 drivers/net/usb/aqc111.c | 60 +++-
 1 file changed, 59 insertions(+), 1 deletion(-)

diff --git a/drivers/net/usb/aqc111.c b/drivers/net/usb/aqc111.c
index 90061157b7ac..e197824f96f1 100644
--- a/drivers/net/usb/aqc111.c
+++ b/drivers/net/usb/aqc111.c
@@ -285,6 +285,48 @@ static void aqc111_set_phy_speed(struct usbnet *dev, u8 
autoneg, u16 speed)
aqc111_set_phy_speed_fw_iface(dev, aqc111_data);
 }
 
+static int aqc111_change_mtu(struct net_device *net, int new_mtu)
+{
+   struct usbnet *dev = netdev_priv(net);
+   u16 reg16 = 0;
+   u8 buf[5];
+
+   net->mtu = new_mtu;
+   dev->hard_mtu = net->mtu + net->hard_header_len;
+
+   aqc111_read16_cmd(dev, AQ_ACCESS_MAC, SFR_MEDIUM_STATUS_MODE,
+ 2, ®16);
+   if (net->mtu > 1500)
+   reg16 |= SFR_MEDIUM_JUMBO_EN;
+   else
+   reg16 &= ~SFR_MEDIUM_JUMBO_EN;
+
+   aqc111_write16_cmd(dev, AQ_ACCESS_MAC, SFR_MEDIUM_STATUS_MODE,
+  2, ®16);
+
+   if (dev->net->mtu > 12500 && dev->net->mtu <= 16334) {
+   memcpy(buf, &AQC111_BULKIN_SIZE[2], 5);
+   /* RX bulk configuration */
+   aqc111_write_cmd(dev, AQ_ACCESS_MAC, SFR_RX_BULKIN_QCTRL,
+5, 5, buf);
+   }
+
+   /* Set high low water level */
+   if (dev->net->mtu <= 4500)
+   reg16 = 0x0810;
+   else if (dev->net->mtu <= 9500)
+   reg16 = 0x1020;
+   else if (dev->net->mtu <= 12500)
+   reg16 = 0x1420;
+   else if (dev->net->mtu <= 16334)
+   reg16 = 0x1A20;
+
+   aqc111_write16_cmd(dev, AQ_ACCESS_MAC, SFR_PAUSE_WATERLVL_LOW,
+  2, ®16);
+
+   return 0;
+}
+
 static int aqc111_set_mac_addr(struct net_device *net, void *p)
 {
struct usbnet *dev = netdev_priv(net);
@@ -305,6 +347,7 @@ static const struct net_device_ops aqc111_netdev_ops = {
.ndo_start_xmit = usbnet_start_xmit,
.ndo_tx_timeout = usbnet_tx_timeout,
.ndo_get_stats64= usbnet_get_stats64,
+   .ndo_change_mtu = aqc111_change_mtu,
.ndo_set_mac_address= aqc111_set_mac_addr,
.ndo_validate_addr  = eth_validate_addr,
 };
@@ -383,6 +426,8 @@ static int aqc111_bind(struct usbnet *dev, struct 
usb_interface *intf)
dev->net->needed_headroom += sizeof(u64);
dev->net->needed_tailroom += sizeof(u64);
 
+   dev->net->max_mtu = 16334;
+
dev->net->netdev_ops = &aqc111_netdev_ops;
 
if (usb_device_no_sg_constraint(dev->udev))
@@ -524,12 +569,22 @@ static void aqc111_configure_rx(struct usbnet *dev,
break;
}
 
+   if (dev->net->mtu > 12500 && dev->net->mtu <= 16334)
+   queue_num = 2; /* For Jumbo packet 16KB */
+
memcpy(buf, &AQC111_BULKIN_SIZE[queue_num], 5);
/* RX bulk configuration */
aqc111_write_cmd(dev, AQ_ACCESS_MAC, SFR_RX_BULKIN_QCTRL, 5, 5, buf);
 
/* Set high low water level */
-   reg16 = 0x0810;
+   if (dev->net->mtu <= 4500)
+   reg16 = 0x0810;
+   else if (dev->net->mtu <= 9500)
+   reg16 = 0x1020;
+   else if (dev->net->mtu <= 12500)
+   reg16 = 0x1420;
+   else if (dev->net->mtu <= 16334)
+   reg16 = 0x1A20;
 
aqc111_write16_cmd(dev, AQ_ACCESS_MAC, SFR_PAUSE_WATERLVL_LOW,
   2, ®16);
@@ -604,6 +659,9 @@ static int aqc111_link_reset(struct usbnet *dev)
aqc111_read16_cmd(dev, AQ_ACCESS_MAC, SFR_MEDIUM_STATUS_MODE,
  2, ®16);
 
+   if (dev->net->mtu > 1500)
+   reg16 |= SFR_MEDIUM_JUMBO_EN;
+
reg16 |= SFR_MEDIUM_RECEIVE_EN | SFR_MEDIUM_RXFLOW_CTRLEN |
 SFR_MEDIUM_TXFLOW_CTRLEN;
aqc111_write16_cmd(dev, AQ_ACCESS_MAC, SFR_MEDIUM_STATUS_MODE,
-- 
2.7.4



[PATCH v2 net-next 14/21] net: usb: aqc111: Implement set_rx_mode callback

2018-11-13 Thread Igor Russkikh
From: Dmitry Bezrukov 

Signed-off-by: Dmitry Bezrukov 
Signed-off-by: Igor Russkikh 
---
 drivers/net/usb/aqc111.c | 72 
 drivers/net/usb/aqc111.h |  4 +++
 2 files changed, 71 insertions(+), 5 deletions(-)

diff --git a/drivers/net/usb/aqc111.c b/drivers/net/usb/aqc111.c
index 2cbdca3d8dfc..65f65fd043f2 100644
--- a/drivers/net/usb/aqc111.c
+++ b/drivers/net/usb/aqc111.c
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -158,6 +159,25 @@ static int aqc111_write32_cmd(struct usbnet *dev, u8 cmd, 
u16 value,
return aqc111_write_cmd(dev, cmd, value, index, sizeof(tmp), &tmp);
 }
 
+static int aqc111_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value,
+ u16 index, u16 size, void *data)
+{
+   return usbnet_write_cmd_async(dev, cmd, USB_DIR_OUT | USB_TYPE_VENDOR |
+ USB_RECIP_DEVICE, value, index, data,
+ size);
+}
+
+static int aqc111_write16_cmd_async(struct usbnet *dev, u8 cmd, u16 value,
+   u16 index, u16 *data)
+{
+   u16 tmp = *data;
+
+   cpu_to_le16s(&tmp);
+
+   return aqc111_write_cmd_async(dev, cmd, value, index,
+ sizeof(tmp), &tmp);
+}
+
 static int aqc111_mdio_read(struct usbnet *dev, u16 value, u16 index, u16 
*data)
 {
return aqc111_read16_cmd(dev, AQ_PHY_CMD, value, index, data);
@@ -341,6 +361,43 @@ static int aqc111_set_mac_addr(struct net_device *net, 
void *p)
ETH_ALEN, net->dev_addr);
 }
 
+static void aqc111_set_rx_mode(struct net_device *net)
+{
+   struct usbnet *dev = netdev_priv(net);
+   struct aqc111_data *aqc111_data = dev->driver_priv;
+   int mc_count = 0;
+
+   mc_count = netdev_mc_count(net);
+
+   aqc111_data->rxctl &= ~(SFR_RX_CTL_PRO | SFR_RX_CTL_AMALL |
+   SFR_RX_CTL_AM);
+
+   if (net->flags & IFF_PROMISC) {
+   aqc111_data->rxctl |= SFR_RX_CTL_PRO;
+   } else if ((net->flags & IFF_ALLMULTI) || mc_count > AQ_MAX_MCAST) {
+   aqc111_data->rxctl |= SFR_RX_CTL_AMALL;
+   } else if (!netdev_mc_empty(net)) {
+   u8 m_filter[AQ_MCAST_FILTER_SIZE] = { 0 };
+   struct netdev_hw_addr *ha = NULL;
+   u32 crc_bits = 0;
+
+   netdev_for_each_mc_addr(ha, net) {
+   crc_bits = ether_crc(ETH_ALEN, ha->addr) >> 26;
+   m_filter[crc_bits >> 3] |= BIT(crc_bits & 7);
+   }
+
+   aqc111_write_cmd_async(dev, AQ_ACCESS_MAC,
+  SFR_MULTI_FILTER_ARRY,
+  AQ_MCAST_FILTER_SIZE,
+  AQ_MCAST_FILTER_SIZE, m_filter);
+
+   aqc111_data->rxctl |= SFR_RX_CTL_AM;
+   }
+
+   aqc111_write16_cmd_async(dev, AQ_ACCESS_MAC, SFR_RX_CTL,
+2, &aqc111_data->rxctl);
+}
+
 static int aqc111_set_features(struct net_device *net,
   netdev_features_t features)
 {
@@ -390,6 +447,7 @@ static const struct net_device_ops aqc111_netdev_ops = {
.ndo_change_mtu = aqc111_change_mtu,
.ndo_set_mac_address= aqc111_set_mac_addr,
.ndo_validate_addr  = eth_validate_addr,
+   .ndo_set_rx_mode= aqc111_set_rx_mode,
.ndo_set_features   = aqc111_set_features,
 };
 
@@ -677,6 +735,7 @@ static int aqc111_link_reset(struct usbnet *dev)
aqc111_write_cmd(dev, AQ_ACCESS_MAC, SFR_ARC_CTRL, 1, 1, ®8);
 
reg16 = SFR_RX_CTL_IPE | SFR_RX_CTL_AB;
+   aqc111_data->rxctl = reg16;
aqc111_write16_cmd(dev, AQ_ACCESS_MAC, SFR_RX_CTL, 2, ®16);
 
reg8 = SFR_RX_PATH_READY;
@@ -697,6 +756,8 @@ static int aqc111_link_reset(struct usbnet *dev)
 
aqc111_configure_csum_offload(dev);
 
+   aqc111_set_rx_mode(dev->net);
+
aqc111_read16_cmd(dev, AQ_ACCESS_MAC, SFR_MEDIUM_STATUS_MODE,
  2, ®16);
 
@@ -708,8 +769,9 @@ static int aqc111_link_reset(struct usbnet *dev)
aqc111_write16_cmd(dev, AQ_ACCESS_MAC, SFR_MEDIUM_STATUS_MODE,
   2, ®16);
 
-   reg16 = SFR_RX_CTL_IPE | SFR_RX_CTL_AB | SFR_RX_CTL_START;
-   aqc111_write16_cmd(dev, AQ_ACCESS_MAC, SFR_RX_CTL, 2, ®16);
+   aqc111_data->rxctl |= SFR_RX_CTL_START;
+   aqc111_write16_cmd(dev, AQ_ACCESS_MAC, SFR_RX_CTL,
+  2, &aqc111_data->rxctl);
 
netif_carrier_on(dev->net);
} else {
@@ -719,9 +781,9 @@ static int aqc111_link_reset(struct usbnet *dev)
aqc111_write16_cmd(dev, AQ_ACCESS_MAC, SFR_MEDIUM_STATUS_MODE,
 

[PATCH v2 net-next 21/21] net: usb: aqc111: Extend cdc_ether blacklist

2018-11-13 Thread Igor Russkikh
From: Dmitry Bezrukov 

Added Aquantia and ASIX device IDs to prevent loading cdc_ether for
these devices. Our firmware reports CDC configuration simultaneously
with vendor specific.

Signed-off-by: Dmitry Bezrukov 
Signed-off-by: Igor Russkikh 
---
 drivers/net/usb/cdc_ether.c | 23 +++
 1 file changed, 23 insertions(+)

diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index 5c42cf81a08b..22527baa8467 100644
--- a/drivers/net/usb/cdc_ether.c
+++ b/drivers/net/usb/cdc_ether.c
@@ -562,6 +562,8 @@ static const struct driver_info wwan_info = {
 #define MICROSOFT_VENDOR_ID0x045e
 #define UBLOX_VENDOR_ID0x1546
 #define TPLINK_VENDOR_ID   0x2357
+#define AQUANTIA_VENDOR_ID 0x2eca
+#define ASIX_VENDOR_ID 0x0b95
 
 static const struct usb_device_id  products[] = {
 /* BLACKLIST !!
@@ -821,6 +823,27 @@ static const struct usb_device_id  products[] = {
.driver_info = 0,
 },
 
+/* Aquantia AQtion USB to 5GbE Controller (based on AQC111U) */
+{
+   USB_DEVICE_AND_INTERFACE_INFO(AQUANTIA_VENDOR_ID, 0xc101, 
USB_CLASS_COMM,
+   USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
+   .driver_info = 0,
+},
+
+/* ASIX USB 3.1 Gen1 to 5G Multi-Gigabit Ethernet Adapter (based on AQC111U) */
+{
+   USB_DEVICE_AND_INTERFACE_INFO(ASIX_VENDOR_ID, 0x2790, USB_CLASS_COMM,
+   USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
+   .driver_info = 0,
+},
+
+/* ASIX USB 3.1 Gen1 to 2.5G Multi-Gigabit Ethernet Adapter (based on AQC112U) 
*/
+{
+   USB_DEVICE_AND_INTERFACE_INFO(ASIX_VENDOR_ID, 0x2791, USB_CLASS_COMM,
+   USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
+   .driver_info = 0,
+},
+
 /* WHITELIST!!!
  *
  * CDC Ether uses two interfaces, not necessarily consecutive.
-- 
2.7.4



[PATCH v2 net-next 04/21] net: usb: aqc111: Various callbacks implementation

2018-11-13 Thread Igor Russkikh
From: Dmitry Bezrukov 

Reset, stop callbacks, driver unbind callback.
More register defines required for these callbacks.
Add helpers to read/write 16bit values

Signed-off-by: Dmitry Bezrukov 
Signed-off-by: Igor Russkikh 
---
 drivers/net/usb/aqc111.c |  76 +++
 drivers/net/usb/aqc111.h | 101 +++
 2 files changed, 177 insertions(+)

diff --git a/drivers/net/usb/aqc111.c b/drivers/net/usb/aqc111.c
index 34ed841b81dc..b08af34a5417 100644
--- a/drivers/net/usb/aqc111.c
+++ b/drivers/net/usb/aqc111.c
@@ -48,6 +48,17 @@ static int aqc111_read_cmd(struct usbnet *dev, u8 cmd, u16 
value,
return ret;
 }
 
+static int aqc111_read16_cmd(struct usbnet *dev, u8 cmd, u16 value,
+u16 index, u16 *data)
+{
+   int ret = 0;
+
+   ret = aqc111_read_cmd(dev, cmd, value, index, sizeof(*data), data);
+   le16_to_cpus(data);
+
+   return ret;
+}
+
 static int __aqc111_write_cmd(struct usbnet *dev, u8 cmd, u8 reqtype,
  u16 value, u16 index, u16 size, const void *data)
 {
@@ -106,6 +117,26 @@ static int aqc111_write_cmd(struct usbnet *dev, u8 cmd, 
u16 value,
return ret;
 }
 
+static int aqc111_write16_cmd_nopm(struct usbnet *dev, u8 cmd, u16 value,
+  u16 index, u16 *data)
+{
+   u16 tmp = *data;
+
+   cpu_to_le16s(&tmp);
+
+   return aqc111_write_cmd_nopm(dev, cmd, value, index, sizeof(tmp), &tmp);
+}
+
+static int aqc111_write16_cmd(struct usbnet *dev, u8 cmd, u16 value,
+ u16 index, u16 *data)
+{
+   u16 tmp = *data;
+
+   cpu_to_le16s(&tmp);
+
+   return aqc111_write_cmd(dev, cmd, value, index, sizeof(tmp), &tmp);
+}
+
 static const struct net_device_ops aqc111_netdev_ops = {
.ndo_open   = usbnet_open,
.ndo_stop   = usbnet_stop,
@@ -137,12 +168,57 @@ static int aqc111_bind(struct usbnet *dev, struct 
usb_interface *intf)
 
 static void aqc111_unbind(struct usbnet *dev, struct usb_interface *intf)
 {
+   u16 reg16;
+
+   /* Force bz */
+   reg16 = SFR_PHYPWR_RSTCTL_BZ;
+   aqc111_write16_cmd_nopm(dev, AQ_ACCESS_MAC, SFR_PHYPWR_RSTCTL,
+   2, ®16);
+   reg16 = 0;
+   aqc111_write16_cmd_nopm(dev, AQ_ACCESS_MAC, SFR_PHYPWR_RSTCTL,
+   2, ®16);
+}
+
+static int aqc111_reset(struct usbnet *dev)
+{
+   u8 reg8 = 0;
+
+   reg8 = 0xFF;
+   aqc111_write_cmd(dev, AQ_ACCESS_MAC, SFR_BM_INT_MASK, 1, 1, ®8);
+
+   reg8 = 0x0;
+   aqc111_write_cmd(dev, AQ_ACCESS_MAC, SFR_SWP_CTRL, 1, 1, ®8);
+
+   aqc111_read_cmd(dev, AQ_ACCESS_MAC, SFR_MONITOR_MODE, 1, 1, ®8);
+   reg8 &= ~(SFR_MONITOR_MODE_EPHYRW | SFR_MONITOR_MODE_RWLC |
+ SFR_MONITOR_MODE_RWMP | SFR_MONITOR_MODE_RWWF |
+ SFR_MONITOR_MODE_RW_FLAG);
+   aqc111_write_cmd(dev, AQ_ACCESS_MAC, SFR_MONITOR_MODE, 1, 1, ®8);
+
+   return 0;
+}
+
+static int aqc111_stop(struct usbnet *dev)
+{
+   u16 reg16 = 0;
+
+   aqc111_read16_cmd(dev, AQ_ACCESS_MAC, SFR_MEDIUM_STATUS_MODE,
+ 2, ®16);
+   reg16 &= ~SFR_MEDIUM_RECEIVE_EN;
+   aqc111_write16_cmd(dev, AQ_ACCESS_MAC, SFR_MEDIUM_STATUS_MODE,
+  2, ®16);
+   reg16 = 0;
+   aqc111_write16_cmd(dev, AQ_ACCESS_MAC, SFR_RX_CTL, 2, ®16);
+
+   return 0;
 }
 
 static const struct driver_info aqc111_info = {
.description= "Aquantia AQtion USB to 5GbE Controller",
.bind   = aqc111_bind,
.unbind = aqc111_unbind,
+   .reset  = aqc111_reset,
+   .stop   = aqc111_stop,
 };
 
 #define AQC111_USB_ETH_DEV(vid, pid, table) \
diff --git a/drivers/net/usb/aqc111.h b/drivers/net/usb/aqc111.h
index f4302f7f0cc3..a252ccd78559 100644
--- a/drivers/net/usb/aqc111.h
+++ b/drivers/net/usb/aqc111.h
@@ -10,9 +10,110 @@
 #ifndef __LINUX_USBNET_AQC111_H
 #define __LINUX_USBNET_AQC111_H
 
+#define AQ_ACCESS_MAC  0x01
 #define AQ_PHY_POWER   0x31
 
 #define AQ_USB_PHY_SET_TIMEOUT 1
 #define AQ_USB_SET_TIMEOUT 4000
 
+/* SFR Reg. /
+
+#define SFR_GENERAL_STATUS 0x03
+#define SFR_CHIP_STATUS0x05
+#define SFR_RX_CTL 0x0B
+   #define SFR_RX_CTL_TXPADCRC 0x0400
+   #define SFR_RX_CTL_IPE  0x0200
+   #define SFR_RX_CTL_DROPCRCERR   0x0100
+   #define SFR_RX_CTL_START0x0080
+   #define SFR_RX_CTL_RF_WAK   0x0040
+   #define SFR_RX_CTL_AP   0x0020
+   #define SFR_RX_CTL_AM   0x0010
+   #define SFR_RX_CTL_AB   0x0008
+   #define SFR_RX_CTL_AMALL0x0002
+   #define SFR_RX_CTL_PRO  0x

[PATCH v2 net-next 19/21] net: usb: aqc111: Add support for wake on LAN by MAGIC packet

2018-11-13 Thread Igor Russkikh
From: Dmitry Bezrukov 

Signed-off-by: Dmitry Bezrukov 
Signed-off-by: Igor Russkikh 
---
 drivers/net/usb/aqc111.c | 215 +++
 drivers/net/usb/aqc111.h |  12 +++
 2 files changed, 227 insertions(+)

diff --git a/drivers/net/usb/aqc111.c b/drivers/net/usb/aqc111.c
index 80fedf2ab2dd..16d1934cc815 100644
--- a/drivers/net/usb/aqc111.c
+++ b/drivers/net/usb/aqc111.c
@@ -53,6 +53,17 @@ static int aqc111_read_cmd(struct usbnet *dev, u8 cmd, u16 
value,
return ret;
 }
 
+static int aqc111_read16_cmd_nopm(struct usbnet *dev, u8 cmd, u16 value,
+ u16 index, u16 *data)
+{
+   int ret = 0;
+
+   ret = aqc111_read_cmd_nopm(dev, cmd, value, index, sizeof(*data), data);
+   le16_to_cpus(data);
+
+   return ret;
+}
+
 static int aqc111_read16_cmd(struct usbnet *dev, u8 cmd, u16 value,
 u16 index, u16 *data)
 {
@@ -209,6 +220,35 @@ static void aqc111_get_drvinfo(struct net_device *net,
info->regdump_len = 0x00;
 }
 
+static void aqc111_get_wol(struct net_device *net,
+  struct ethtool_wolinfo *wolinfo)
+{
+   struct usbnet *dev = netdev_priv(net);
+   struct aqc111_data *aqc111_data = dev->driver_priv;
+
+   wolinfo->supported = WAKE_MAGIC;
+   wolinfo->wolopts = 0;
+
+   if (aqc111_data->wol_flags & AQ_WOL_FLAG_MP)
+   wolinfo->wolopts |= WAKE_MAGIC;
+}
+
+static int aqc111_set_wol(struct net_device *net,
+ struct ethtool_wolinfo *wolinfo)
+{
+   struct usbnet *dev = netdev_priv(net);
+   struct aqc111_data *aqc111_data = dev->driver_priv;
+
+   if (wolinfo->wolopts & ~WAKE_MAGIC)
+   return -EINVAL;
+
+   aqc111_data->wol_flags = 0;
+   if (wolinfo->wolopts & WAKE_MAGIC)
+   aqc111_data->wol_flags |= AQ_WOL_FLAG_MP;
+
+   return 0;
+}
+
 static void aqc111_speed_to_link_mode(u32 speed,
  struct ethtool_link_ksettings *elk)
 {
@@ -449,6 +489,8 @@ static int aqc111_set_link_ksettings(struct net_device *net,
 
 static const struct ethtool_ops aqc111_ethtool_ops = {
.get_drvinfo = aqc111_get_drvinfo,
+   .get_wol = aqc111_get_wol,
+   .set_wol = aqc111_set_wol,
.get_msglevel = usbnet_get_msglevel,
.set_msglevel = usbnet_set_msglevel,
.get_link = ethtool_op_get_link,
@@ -1327,6 +1369,177 @@ static const struct driver_info aqc111_info = {
.tx_fixup   = aqc111_tx_fixup,
 };
 
+static int aqc111_suspend(struct usb_interface *intf, pm_message_t message)
+{
+   struct usbnet *dev = usb_get_intfdata(intf);
+   struct aqc111_data *aqc111_data = dev->driver_priv;
+   u16 temp_rx_ctrl = 0x00;
+   u16 reg16;
+   u8 reg8;
+
+   usbnet_suspend(intf, message);
+
+   aqc111_read16_cmd_nopm(dev, AQ_ACCESS_MAC, SFR_RX_CTL, 2, ®16);
+   temp_rx_ctrl = reg16;
+   /* Stop RX operations*/
+   reg16 &= ~SFR_RX_CTL_START;
+   aqc111_write16_cmd_nopm(dev, AQ_ACCESS_MAC, SFR_RX_CTL, 2, ®16);
+   /* Force bz */
+   aqc111_read16_cmd_nopm(dev, AQ_ACCESS_MAC, SFR_PHYPWR_RSTCTL,
+  2, ®16);
+   reg16 |= SFR_PHYPWR_RSTCTL_BZ;
+   aqc111_write16_cmd_nopm(dev, AQ_ACCESS_MAC, SFR_PHYPWR_RSTCTL,
+   2, ®16);
+
+   reg8 = SFR_BULK_OUT_EFF_EN;
+   aqc111_write_cmd_nopm(dev, AQ_ACCESS_MAC, SFR_BULK_OUT_CTRL,
+ 1, 1, ®8);
+
+   temp_rx_ctrl &= ~(SFR_RX_CTL_START | SFR_RX_CTL_RF_WAK |
+ SFR_RX_CTL_AP | SFR_RX_CTL_AM);
+   aqc111_write16_cmd_nopm(dev, AQ_ACCESS_MAC, SFR_RX_CTL,
+   2, &temp_rx_ctrl);
+
+   reg8 = 0x00;
+   aqc111_write_cmd_nopm(dev, AQ_ACCESS_MAC, SFR_ETH_MAC_PATH,
+ 1, 1, ®8);
+
+   if (aqc111_data->wol_flags) {
+   struct aqc111_wol_cfg wol_cfg = { 0 };
+
+   aqc111_data->phy_cfg |= AQ_WOL;
+   if (aqc111_data->dpa) {
+   reg8 = 0;
+   if (aqc111_data->wol_flags & AQ_WOL_FLAG_MP)
+   reg8 |= SFR_MONITOR_MODE_RWMP;
+   aqc111_write_cmd_nopm(dev, AQ_ACCESS_MAC,
+ SFR_MONITOR_MODE, 1, 1, ®8);
+   } else {
+   ether_addr_copy(wol_cfg.hw_addr, dev->net->dev_addr);
+   wol_cfg.flags = aqc111_data->wol_flags;
+   }
+
+   temp_rx_ctrl |= (SFR_RX_CTL_AB | SFR_RX_CTL_START);
+   aqc111_write16_cmd_nopm(dev, AQ_ACCESS_MAC, SFR_RX_CTL,
+   2, &temp_rx_ctrl);
+   reg8 = 0x00;
+   aqc111_write_cmd_nopm(dev, AQ_ACCESS_MAC, SFR_BM_INT_MASK,
+ 1, 1, ®8);
+   reg8 = SFR_BMRX_DMA_EN;
+   aqc111_write_

[PATCH v2 net-next 16/21] net: usb: aqc111: Add RX VLAN filtering support

2018-11-13 Thread Igor Russkikh
From: Dmitry Bezrukov 

Signed-off-by: Dmitry Bezrukov 
Signed-off-by: Igor Russkikh 
---
 drivers/net/usb/aqc111.c | 89 
 drivers/net/usb/aqc111.h |  2 +-
 2 files changed, 90 insertions(+), 1 deletion(-)

diff --git a/drivers/net/usb/aqc111.c b/drivers/net/usb/aqc111.c
index 778d8199031e..34e09492fb0e 100644
--- a/drivers/net/usb/aqc111.c
+++ b/drivers/net/usb/aqc111.c
@@ -361,6 +361,57 @@ static int aqc111_set_mac_addr(struct net_device *net, 
void *p)
ETH_ALEN, net->dev_addr);
 }
 
+static int aqc111_vlan_rx_kill_vid(struct net_device *net,
+  __be16 proto, u16 vid)
+{
+   struct usbnet *dev = netdev_priv(net);
+   u8 vlan_ctrl = 0;
+   u16 reg16 = 0;
+   u8 reg8 = 0;
+
+   aqc111_read_cmd(dev, AQ_ACCESS_MAC, SFR_VLAN_ID_CONTROL, 1, 1, ®8);
+   vlan_ctrl = reg8;
+
+   /* Address */
+   reg8 = (vid / 16);
+   aqc111_write_cmd(dev, AQ_ACCESS_MAC, SFR_VLAN_ID_ADDRESS, 1, 1, ®8);
+   /* Data */
+   reg8 = vlan_ctrl | SFR_VLAN_CONTROL_RD;
+   aqc111_write_cmd(dev, AQ_ACCESS_MAC, SFR_VLAN_ID_CONTROL, 1, 1, ®8);
+   aqc111_read16_cmd(dev, AQ_ACCESS_MAC, SFR_VLAN_ID_DATA0, 2, ®16);
+   reg16 &= ~(1 << (vid % 16));
+   aqc111_write16_cmd(dev, AQ_ACCESS_MAC, SFR_VLAN_ID_DATA0, 2, ®16);
+   reg8 = vlan_ctrl | SFR_VLAN_CONTROL_WE;
+   aqc111_write_cmd(dev, AQ_ACCESS_MAC, SFR_VLAN_ID_CONTROL, 1, 1, ®8);
+
+   return 0;
+}
+
+static int aqc111_vlan_rx_add_vid(struct net_device *net, __be16 proto, u16 
vid)
+{
+   struct usbnet *dev = netdev_priv(net);
+   u8 vlan_ctrl = 0;
+   u16 reg16 = 0;
+   u8 reg8 = 0;
+
+   aqc111_read_cmd(dev, AQ_ACCESS_MAC, SFR_VLAN_ID_CONTROL, 1, 1, ®8);
+   vlan_ctrl = reg8;
+
+   /* Address */
+   reg8 = (vid / 16);
+   aqc111_write_cmd(dev, AQ_ACCESS_MAC, SFR_VLAN_ID_ADDRESS, 1, 1, ®8);
+   /* Data */
+   reg8 = vlan_ctrl | SFR_VLAN_CONTROL_RD;
+   aqc111_write_cmd(dev, AQ_ACCESS_MAC, SFR_VLAN_ID_CONTROL, 1, 1, ®8);
+   aqc111_read16_cmd(dev, AQ_ACCESS_MAC, SFR_VLAN_ID_DATA0, 2, ®16);
+   reg16 |= (1 << (vid % 16));
+   aqc111_write16_cmd(dev, AQ_ACCESS_MAC, SFR_VLAN_ID_DATA0, 2, ®16);
+   reg8 = vlan_ctrl | SFR_VLAN_CONTROL_WE;
+   aqc111_write_cmd(dev, AQ_ACCESS_MAC, SFR_VLAN_ID_CONTROL, 1, 1, ®8);
+
+   return 0;
+}
+
 static void aqc111_set_rx_mode(struct net_device *net)
 {
struct usbnet *dev = netdev_priv(net);
@@ -404,6 +455,7 @@ static int aqc111_set_features(struct net_device *net,
struct usbnet *dev = netdev_priv(net);
struct aqc111_data *aqc111_data = dev->driver_priv;
netdev_features_t changed = net->features ^ features;
+   u16 reg16 = 0;
u8 reg8 = 0;
 
if (changed & NETIF_F_IP_CSUM) {
@@ -435,6 +487,39 @@ static int aqc111_set_features(struct net_device *net,
aqc111_write_cmd(dev, AQ_ACCESS_MAC, SFR_RXCOE_CTL,
 1, 1, ®8);
}
+   if (changed & NETIF_F_HW_VLAN_CTAG_FILTER) {
+   if (features & NETIF_F_HW_VLAN_CTAG_FILTER) {
+   u16 i = 0;
+
+   for (i = 0; i < 256; i++) {
+   /* Address */
+   reg8 = i;
+   aqc111_write_cmd(dev, AQ_ACCESS_MAC,
+SFR_VLAN_ID_ADDRESS,
+1, 1, ®8);
+   /* Data */
+   aqc111_write16_cmd(dev, AQ_ACCESS_MAC,
+  SFR_VLAN_ID_DATA0,
+  2, ®16);
+   reg8 = SFR_VLAN_CONTROL_WE;
+   aqc111_write_cmd(dev, AQ_ACCESS_MAC,
+SFR_VLAN_ID_CONTROL,
+1, 1, ®8);
+   }
+   aqc111_read_cmd(dev, AQ_ACCESS_MAC, SFR_VLAN_ID_CONTROL,
+   1, 1, ®8);
+   reg8 |= SFR_VLAN_CONTROL_VFE;
+   aqc111_write_cmd(dev, AQ_ACCESS_MAC,
+SFR_VLAN_ID_CONTROL, 1, 1, ®8);
+   } else {
+   aqc111_read_cmd(dev, AQ_ACCESS_MAC, SFR_VLAN_ID_CONTROL,
+   1, 1, ®8);
+   reg8 &= ~SFR_VLAN_CONTROL_VFE;
+   aqc111_write_cmd(dev, AQ_ACCESS_MAC,
+SFR_VLAN_ID_CONTROL, 1, 1, ®8);
+   }
+   }
+
return 0;
 }
 
@@ -447,6 +532,8 @@ static const struct net_device_ops aqc111_netdev_ops = {
.ndo_change_mtu = aqc111_change_mtu,
.ndo_set_mac_address= aqc111_set_mac_addr,
 

[PATCH v2 net-next 20/21] net: usb: aqc111: Add ASIX's HW ids

2018-11-13 Thread Igor Russkikh
From: Dmitry Bezrukov 

It enables driver for ASIX products which are also based on aqc111/112U chips.

Signed-off-by: Dmitry Bezrukov 
Signed-off-by: Igor Russkikh 
---
 drivers/net/usb/aqc111.c | 40 
 1 file changed, 40 insertions(+)

diff --git a/drivers/net/usb/aqc111.c b/drivers/net/usb/aqc111.c
index 16d1934cc815..3ae1dcc1178e 100644
--- a/drivers/net/usb/aqc111.c
+++ b/drivers/net/usb/aqc111.c
@@ -1369,6 +1369,44 @@ static const struct driver_info aqc111_info = {
.tx_fixup   = aqc111_tx_fixup,
 };
 
+#define ASIX111_DESC \
+"ASIX USB 3.1 Gen1 to 5G Multi-Gigabit Ethernet Adapter"
+
+static const struct driver_info asix111_info = {
+   .description= ASIX111_DESC,
+   .bind   = aqc111_bind,
+   .unbind = aqc111_unbind,
+   .status = aqc111_status,
+   .link_reset = aqc111_link_reset,
+   .reset  = aqc111_reset,
+   .stop   = aqc111_stop,
+   .flags  = FLAG_ETHER | FLAG_FRAMING_AX |
+ FLAG_AVOID_UNLINK_URBS | FLAG_MULTI_PACKET,
+   .rx_fixup   = aqc111_rx_fixup,
+   .tx_fixup   = aqc111_tx_fixup,
+};
+
+#undef ASIX111_DESC
+
+#define ASIX112_DESC \
+"ASIX USB 3.1 Gen1 to 2.5G Multi-Gigabit Ethernet Adapter"
+
+static const struct driver_info asix112_info = {
+   .description= ASIX112_DESC,
+   .bind   = aqc111_bind,
+   .unbind = aqc111_unbind,
+   .status = aqc111_status,
+   .link_reset = aqc111_link_reset,
+   .reset  = aqc111_reset,
+   .stop   = aqc111_stop,
+   .flags  = FLAG_ETHER | FLAG_FRAMING_AX |
+ FLAG_AVOID_UNLINK_URBS | FLAG_MULTI_PACKET,
+   .rx_fixup   = aqc111_rx_fixup,
+   .tx_fixup   = aqc111_tx_fixup,
+};
+
+#undef ASIX112_DESC
+
 static int aqc111_suspend(struct usb_interface *intf, pm_message_t message)
 {
struct usbnet *dev = usb_get_intfdata(intf);
@@ -1546,6 +1584,8 @@ static int aqc111_resume(struct usb_interface *intf)
 
 static const struct usb_device_id products[] = {
{AQC111_USB_ETH_DEV(0x2eca, 0xc101, aqc111_info)},
+   {AQC111_USB_ETH_DEV(0x0b95, 0x2790, asix111_info)},
+   {AQC111_USB_ETH_DEV(0x0b95, 0x2791, asix112_info)},
{ },/* END */
 };
 MODULE_DEVICE_TABLE(usb, products);
-- 
2.7.4



[PATCH v2 net-next 05/21] net: usb: aqc111: Introduce PHY access

2018-11-13 Thread Igor Russkikh
From: Dmitry Bezrukov 

Add helpers to write 32bit values.
Implement PHY power up/down sequences.
AQC111, depending on FW used, may has PHY being controlled either
directly (dpa = 1) or via vendor command interface (dpa = 0).
Drivers supports both themes.
We determine this from firmware versioning agreement.

Signed-off-by: Dmitry Bezrukov 
Signed-off-by: Igor Russkikh 
---
 drivers/net/usb/aqc111.c | 109 +++
 drivers/net/usb/aqc111.h |  44 +++
 2 files changed, 153 insertions(+)

diff --git a/drivers/net/usb/aqc111.c b/drivers/net/usb/aqc111.c
index b08af34a5417..c91acb7b7c4e 100644
--- a/drivers/net/usb/aqc111.c
+++ b/drivers/net/usb/aqc111.c
@@ -137,14 +137,62 @@ static int aqc111_write16_cmd(struct usbnet *dev, u8 cmd, 
u16 value,
return aqc111_write_cmd(dev, cmd, value, index, sizeof(tmp), &tmp);
 }
 
+static int aqc111_write32_cmd_nopm(struct usbnet *dev, u8 cmd, u16 value,
+  u16 index, u32 *data)
+{
+   u32 tmp = *data;
+
+   cpu_to_le32s(&tmp);
+
+   return aqc111_write_cmd_nopm(dev, cmd, value, index, sizeof(tmp), &tmp);
+}
+
+static int aqc111_write32_cmd(struct usbnet *dev, u8 cmd, u16 value,
+ u16 index, u32 *data)
+{
+   u32 tmp = *data;
+
+   cpu_to_le32s(&tmp);
+
+   return aqc111_write_cmd(dev, cmd, value, index, sizeof(tmp), &tmp);
+}
+
+static int aqc111_mdio_read(struct usbnet *dev, u16 value, u16 index, u16 
*data)
+{
+   return aqc111_read16_cmd(dev, AQ_PHY_CMD, value, index, data);
+}
+
+static int aqc111_mdio_write(struct usbnet *dev, u16 value,
+u16 index, u16 *data)
+{
+   return aqc111_write16_cmd(dev, AQ_PHY_CMD, value, index, data);
+}
+
 static const struct net_device_ops aqc111_netdev_ops = {
.ndo_open   = usbnet_open,
.ndo_stop   = usbnet_stop,
 };
 
+static void aqc111_read_fw_version(struct usbnet *dev,
+  struct aqc111_data *aqc111_data)
+{
+   aqc111_read_cmd(dev, AQ_ACCESS_MAC, AQ_FW_VER_MAJOR,
+   1, 1, &aqc111_data->fw_ver.major);
+   aqc111_read_cmd(dev, AQ_ACCESS_MAC, AQ_FW_VER_MINOR,
+   1, 1, &aqc111_data->fw_ver.minor);
+   aqc111_read_cmd(dev, AQ_ACCESS_MAC, AQ_FW_VER_REV,
+   1, 1, &aqc111_data->fw_ver.rev);
+
+   if (aqc111_data->fw_ver.major & 0x80)
+   aqc111_data->fw_ver.major &= ~0x80;
+   else
+   aqc111_data->dpa = 1;
+}
+
 static int aqc111_bind(struct usbnet *dev, struct usb_interface *intf)
 {
struct usb_device *udev = interface_to_usbdev(intf);
+   struct aqc111_data *aqc111_data;
int ret;
 
/* Check if vendor configuration */
@@ -161,14 +209,25 @@ static int aqc111_bind(struct usbnet *dev, struct 
usb_interface *intf)
return ret;
}
 
+   aqc111_data = kzalloc(sizeof(*aqc111_data), GFP_KERNEL);
+   if (!aqc111_data)
+   return -ENOMEM;
+
+   /* store aqc111_data pointer in device data field */
+   dev->driver_priv = aqc111_data;
+
dev->net->netdev_ops = &aqc111_netdev_ops;
 
+   aqc111_read_fw_version(dev, aqc111_data);
+
return 0;
 }
 
 static void aqc111_unbind(struct usbnet *dev, struct usb_interface *intf)
 {
+   struct aqc111_data *aqc111_data = dev->driver_priv;
u16 reg16;
+   u8 reg8;
 
/* Force bz */
reg16 = SFR_PHYPWR_RSTCTL_BZ;
@@ -177,12 +236,50 @@ static void aqc111_unbind(struct usbnet *dev, struct 
usb_interface *intf)
reg16 = 0;
aqc111_write16_cmd_nopm(dev, AQ_ACCESS_MAC, SFR_PHYPWR_RSTCTL,
2, ®16);
+
+   /* Power down ethernet PHY */
+   if (aqc111_data->dpa) {
+   reg8 = 0x00;
+   aqc111_write_cmd_nopm(dev, AQ_PHY_POWER, 0,
+ 0, 1, ®8);
+   } else {
+   aqc111_data->phy_cfg |= AQ_LOW_POWER;
+   aqc111_data->phy_cfg &= ~AQ_PHY_POWER_EN;
+   aqc111_write32_cmd_nopm(dev, AQ_PHY_OPS, 0, 0,
+   &aqc111_data->phy_cfg);
+   }
+
+   kfree(aqc111_data);
 }
 
 static int aqc111_reset(struct usbnet *dev)
 {
+   struct aqc111_data *aqc111_data = dev->driver_priv;
+   u16 reg16 = 0;
u8 reg8 = 0;
 
+   /* Power up ethernet PHY */
+   aqc111_data->phy_cfg = AQ_PHY_POWER_EN;
+   if (aqc111_data->dpa) {
+   aqc111_read_cmd(dev, AQ_PHY_POWER, 0, 0, 1, ®8);
+   if (reg8 == 0x00) {
+   reg8 = 0x02;
+   aqc111_write_cmd(dev, AQ_PHY_POWER, 0, 0, 1, ®8);
+   msleep(200);
+   }
+
+   aqc111_mdio_read(dev, AQ_GLB_STD_CTRL_REG, AQ_PHY_GLOBAL_ADDR,
+®16);
+   if (reg16 & AQ_PHY_LOW_POWER_MODE) {
+

[PATCH v2 net-next 17/21] net: usb: aqc111: Initialize ethtool_ops structure

2018-11-13 Thread Igor Russkikh
From: Dmitry Bezrukov 

Implement get_drvinfo, set/get_msglevel, get_link callbacks

Signed-off-by: Dmitry Bezrukov 
Signed-off-by: Igor Russkikh 
---
 drivers/net/usb/aqc111.c | 28 
 1 file changed, 28 insertions(+)

diff --git a/drivers/net/usb/aqc111.c b/drivers/net/usb/aqc111.c
index 34e09492fb0e..b3160b0320eb 100644
--- a/drivers/net/usb/aqc111.c
+++ b/drivers/net/usb/aqc111.c
@@ -9,6 +9,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -18,6 +19,8 @@
 
 #include "aqc111.h"
 
+#define DRIVER_NAME "aqc111"
+
 static int aqc111_read_cmd_nopm(struct usbnet *dev, u8 cmd, u16 value,
u16 index, u16 size, void *data)
 {
@@ -189,6 +192,23 @@ static int aqc111_mdio_write(struct usbnet *dev, u16 value,
return aqc111_write16_cmd(dev, AQ_PHY_CMD, value, index, data);
 }
 
+static void aqc111_get_drvinfo(struct net_device *net,
+  struct ethtool_drvinfo *info)
+{
+   struct usbnet *dev = netdev_priv(net);
+   struct aqc111_data *aqc111_data = dev->driver_priv;
+
+   /* Inherit standard device info */
+   usbnet_get_drvinfo(net, info);
+   strlcpy(info->driver, DRIVER_NAME, sizeof(info->driver));
+   snprintf(info->fw_version, sizeof(info->fw_version), "%u.%u.%u",
+aqc111_data->fw_ver.major,
+aqc111_data->fw_ver.minor,
+aqc111_data->fw_ver.rev);
+   info->eedump_len = 0x00;
+   info->regdump_len = 0x00;
+}
+
 static void aqc111_set_phy_speed_fw_iface(struct usbnet *dev,
  struct aqc111_data *aqc111_data)
 {
@@ -305,6 +325,13 @@ static void aqc111_set_phy_speed(struct usbnet *dev, u8 
autoneg, u16 speed)
aqc111_set_phy_speed_fw_iface(dev, aqc111_data);
 }
 
+static const struct ethtool_ops aqc111_ethtool_ops = {
+   .get_drvinfo = aqc111_get_drvinfo,
+   .get_msglevel = usbnet_get_msglevel,
+   .set_msglevel = usbnet_set_msglevel,
+   .get_link = ethtool_op_get_link,
+};
+
 static int aqc111_change_mtu(struct net_device *net, int new_mtu)
 {
struct usbnet *dev = netdev_priv(net);
@@ -615,6 +642,7 @@ static int aqc111_bind(struct usbnet *dev, struct 
usb_interface *intf)
dev->net->max_mtu = 16334;
 
dev->net->netdev_ops = &aqc111_netdev_ops;
+   dev->net->ethtool_ops = &aqc111_ethtool_ops;
 
if (usb_device_no_sg_constraint(dev->udev))
dev->can_dma_sg = 1;
-- 
2.7.4



[PATCH v2 net-next 06/21] net: usb: aqc111: Introduce link management

2018-11-13 Thread Igor Russkikh
From: Dmitry Bezrukov 

Add full hardware initialization sequence and link configuration logic

Signed-off-by: Dmitry Bezrukov 
Signed-off-by: Igor Russkikh 
---
 drivers/net/usb/aqc111.c | 312 +++
 drivers/net/usb/aqc111.h |  45 +++
 2 files changed, 357 insertions(+)

diff --git a/drivers/net/usb/aqc111.c b/drivers/net/usb/aqc111.c
index c91acb7b7c4e..2b78b5d7d29b 100644
--- a/drivers/net/usb/aqc111.c
+++ b/drivers/net/usb/aqc111.c
@@ -168,6 +168,122 @@ static int aqc111_mdio_write(struct usbnet *dev, u16 
value,
return aqc111_write16_cmd(dev, AQ_PHY_CMD, value, index, data);
 }
 
+static void aqc111_set_phy_speed_fw_iface(struct usbnet *dev,
+ struct aqc111_data *aqc111_data)
+{
+   aqc111_write32_cmd(dev, AQ_PHY_OPS, 0, 0, &aqc111_data->phy_cfg);
+}
+
+static void aqc111_set_phy_speed_direct(struct usbnet *dev,
+   struct aqc111_data *aqc111_data)
+{
+   u16 reg16_1 = 0;
+   u16 reg16_2 = 0;
+   u16 reg16_3 = 0;
+
+   /* Disable auto-negotiation */
+   reg16_1 = AQ_ANEG_EX_PAGE_CTRL;
+   aqc111_mdio_write(dev, AQ_AUTONEG_STD_CTRL_REG, AQ_PHY_AUTONEG_ADDR,
+ ®16_1);
+
+   reg16_1 = AQ_ANEG_EX_PHY_ID | AQ_ANEG_ADV_AQRATE;
+   if (aqc111_data->phy_cfg & AQ_DOWNSHIFT) {
+   reg16_1 |= AQ_ANEG_EN_DSH;
+   reg16_1 |= (aqc111_data->phy_cfg & AQ_DSH_RETRIES_MASK) >>
+   AQ_DSH_RETRIES_SHIFT;
+   }
+
+   reg16_2 = AQ_ANEG_ADV_LT;
+   if (aqc111_data->phy_cfg & AQ_PAUSE)
+   reg16_3 |= AQ_ANEG_PAUSE;
+
+   if (aqc111_data->phy_cfg & AQ_ASYM_PAUSE)
+   reg16_3 |= AQ_ANEG_ASYM_PAUSE;
+
+   if (aqc111_data->phy_cfg & AQ_ADV_5G) {
+   reg16_1 |= AQ_ANEG_ADV_5G_N;
+   reg16_2 |= AQ_ANEG_ADV_5G_T;
+   }
+   if (aqc111_data->phy_cfg & AQ_ADV_2G5) {
+   reg16_1 |= AQ_ANEG_ADV_2G5_N;
+   reg16_2 |= AQ_ANEG_ADV_2G5_T;
+   }
+   if (aqc111_data->phy_cfg & AQ_ADV_1G)
+   reg16_1 |= AQ_ANEG_ADV_1G;
+
+   if (aqc111_data->phy_cfg & AQ_ADV_100M)
+   reg16_3 |= AQ_ANEG_100M;
+
+   aqc111_mdio_write(dev, AQ_AUTONEG_VEN_PROV1_REG,
+ AQ_PHY_AUTONEG_ADDR, ®16_1);
+   aqc111_mdio_write(dev, AQ_AUTONEG_10GT_CTRL_REG,
+ AQ_PHY_AUTONEG_ADDR, ®16_2);
+
+   aqc111_mdio_read(dev, AQ_AUTONEG_ADV_REG, AQ_PHY_AUTONEG_ADDR,
+®16_1);
+   reg16_1 &= ~AQ_ANEG_ABILITY_MASK;
+   reg16_1 |= reg16_3;
+   aqc111_mdio_write(dev, AQ_AUTONEG_ADV_REG, AQ_PHY_AUTONEG_ADDR,
+ ®16_1);
+
+   /* Restart auto-negotiation */
+   reg16_1 = AQ_ANEG_EX_PAGE_CTRL | AQ_ANEG_EN_ANEG |
+ AQ_ANEG_RESTART_ANEG;
+
+   aqc111_mdio_write(dev, AQ_AUTONEG_STD_CTRL_REG,
+ AQ_PHY_AUTONEG_ADDR, ®16_1);
+}
+
+static void aqc111_set_phy_speed(struct usbnet *dev, u8 autoneg, u16 speed)
+{
+   struct aqc111_data *aqc111_data = dev->driver_priv;
+
+   aqc111_data->phy_cfg &= ~AQ_ADV_MASK;
+   aqc111_data->phy_cfg |= AQ_PAUSE;
+   aqc111_data->phy_cfg |= AQ_ASYM_PAUSE;
+   aqc111_data->phy_cfg |= AQ_DOWNSHIFT;
+   aqc111_data->phy_cfg &= ~AQ_DSH_RETRIES_MASK;
+   aqc111_data->phy_cfg |= (3 << AQ_DSH_RETRIES_SHIFT) &
+   AQ_DSH_RETRIES_MASK;
+
+   if (autoneg == AUTONEG_ENABLE) {
+   switch (speed) {
+   case SPEED_5000:
+   aqc111_data->phy_cfg |= AQ_ADV_5G;
+   /* fall-through */
+   case SPEED_2500:
+   aqc111_data->phy_cfg |= AQ_ADV_2G5;
+   /* fall-through */
+   case SPEED_1000:
+   aqc111_data->phy_cfg |= AQ_ADV_1G;
+   /* fall-through */
+   case SPEED_100:
+   aqc111_data->phy_cfg |= AQ_ADV_100M;
+   /* fall-through */
+   }
+   } else {
+   switch (speed) {
+   case SPEED_5000:
+   aqc111_data->phy_cfg |= AQ_ADV_5G;
+   break;
+   case SPEED_2500:
+   aqc111_data->phy_cfg |= AQ_ADV_2G5;
+   break;
+   case SPEED_1000:
+   aqc111_data->phy_cfg |= AQ_ADV_1G;
+   break;
+   case SPEED_100:
+   aqc111_data->phy_cfg |= AQ_ADV_100M;
+   break;
+   }
+   }
+
+   if (aqc111_data->dpa)
+   aqc111_set_phy_speed_direct(dev, aqc111_data);
+   else
+   aqc111_set_phy_speed_fw_iface(dev, aqc111_data);
+}
+
 static const struct net_device_ops aqc111_netdev_ops = {
.ndo_open   = u

[PATCH v2 net-next 15/21] net: usb: aqc111: Add support for VLAN_CTAG_TX/RX offload

2018-11-13 Thread Igor Russkikh
From: Dmitry Bezrukov 

Signed-off-by: Dmitry Bezrukov 
Signed-off-by: Igor Russkikh 
---
 drivers/net/usb/aqc111.c | 17 +
 drivers/net/usb/aqc111.h | 12 +++-
 2 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/drivers/net/usb/aqc111.c b/drivers/net/usb/aqc111.c
index 65f65fd043f2..778d8199031e 100644
--- a/drivers/net/usb/aqc111.c
+++ b/drivers/net/usb/aqc111.c
@@ -534,6 +534,7 @@ static int aqc111_bind(struct usbnet *dev, struct 
usb_interface *intf)
 
dev->net->hw_features |= AQ_SUPPORT_HW_FEATURE;
dev->net->features |= AQ_SUPPORT_FEATURE;
+   dev->net->vlan_features |= AQ_SUPPORT_VLAN_FEATURE;
 
aqc111_read_fw_version(dev, aqc111_data);
aqc111_data->autoneg = AUTONEG_ENABLE;
@@ -810,6 +811,7 @@ static int aqc111_reset(struct usbnet *dev)
 
dev->net->hw_features |= AQ_SUPPORT_HW_FEATURE;
dev->net->features |= AQ_SUPPORT_FEATURE;
+   dev->net->vlan_features |= AQ_SUPPORT_VLAN_FEATURE;
 
/* Power up ethernet PHY */
aqc111_data->phy_cfg = AQ_PHY_POWER_EN;
@@ -912,6 +914,7 @@ static int aqc111_rx_fixup(struct usbnet *dev, struct 
sk_buff *skb)
u32 desc_offset = 0; /*RX Header Offset*/
u16 pkt_count = 0;
u64 desc_hdr = 0;
+   u16 vlan_tag = 0;
u32 skb_len = 0;
 
if (!skb)
@@ -984,6 +987,12 @@ static int aqc111_rx_fixup(struct usbnet *dev, struct 
sk_buff *skb)
if (aqc111_data->rx_checksum)
aqc111_rx_checksum(new_skb, pkt_desc);
 
+   if (*pkt_desc & AQ_RX_PD_VLAN) {
+   vlan_tag = *pkt_desc >> AQ_RX_PD_VLAN_SHIFT;
+   __vlan_hwaccel_put_tag(new_skb, htons(ETH_P_8021Q),
+  vlan_tag & VLAN_VID_MASK);
+   }
+
usbnet_skb_return(dev, new_skb);
if (pkt_count == 0)
break;
@@ -1011,6 +1020,7 @@ static struct sk_buff *aqc111_tx_fixup(struct usbnet 
*dev, struct sk_buff *skb,
int headroom = 0;
int tailroom = 0;
u64 tx_desc = 0;
+   u16 tci = 0;
 
/*Length of actual data*/
tx_desc |= skb->len & AQ_TX_DESC_LEN_MASK;
@@ -1028,6 +1038,13 @@ static struct sk_buff *aqc111_tx_fixup(struct usbnet 
*dev, struct sk_buff *skb,
tx_desc |= AQ_TX_DESC_DROP_PADD;
}
 
+   /* Vlan Tag */
+   if (vlan_get_tag(skb, &tci) >= 0) {
+   tx_desc |= AQ_TX_DESC_VLAN;
+   tx_desc |= ((u64)tci & AQ_TX_DESC_VLAN_MASK) <<
+  AQ_TX_DESC_VLAN_SHIFT;
+   }
+
if (!dev->can_dma_sg && (dev->net->features & NETIF_F_SG) &&
skb_linearize(skb))
return NULL;
diff --git a/drivers/net/usb/aqc111.h b/drivers/net/usb/aqc111.h
index fdd7c1059fac..69113fb8d25f 100644
--- a/drivers/net/usb/aqc111.h
+++ b/drivers/net/usb/aqc111.h
@@ -68,12 +68,17 @@
 /* Feature. /
 #define AQ_SUPPORT_FEATURE (NETIF_F_SG | NETIF_F_IP_CSUM |\
 NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM |\
-NETIF_F_TSO)
+NETIF_F_TSO | NETIF_F_HW_VLAN_CTAG_TX |\
+NETIF_F_HW_VLAN_CTAG_RX)
 
 #define AQ_SUPPORT_HW_FEATURE  (NETIF_F_SG | NETIF_F_IP_CSUM |\
 NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM |\
 NETIF_F_TSO)
 
+#define AQ_SUPPORT_VLAN_FEATURE (NETIF_F_SG | NETIF_F_IP_CSUM |\
+NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM |\
+NETIF_F_TSO)
+
 /* SFR Reg. /
 
 #define SFR_GENERAL_STATUS 0x03
@@ -211,8 +216,11 @@ struct aqc111_data {
 /* TX Descriptor */
 #define AQ_TX_DESC_LEN_MASK0x1F
 #define AQ_TX_DESC_DROP_PADD   BIT(28)
+#define AQ_TX_DESC_VLANBIT(29)
 #define AQ_TX_DESC_MSS_MASK0x7FFF
 #define AQ_TX_DESC_MSS_SHIFT   0x20
+#define AQ_TX_DESC_VLAN_MASK   0x
+#define AQ_TX_DESC_VLAN_SHIFT  0x30
 
 #define AQ_RX_HW_PAD   0x02
 
@@ -226,10 +234,12 @@ struct aqc111_data {
 #define AQ_RX_PD_L3_IP 0x20
 #define AQ_RX_PD_L3_IP60x40
 
+#define AQ_RX_PD_VLAN  BIT(10)
 #define AQ_RX_PD_RX_OK BIT(11)
 #define AQ_RX_PD_DROP  BIT(31)
 #define AQ_RX_PD_LEN_MASK  0x7FFF
 #define AQ_RX_PD_LEN_SHIFT 0x10
+#define AQ_RX_PD_VLAN_SHIFT0x20
 
 /* RX Descriptor header */
 #define AQ_RX_DH_PKT_CNT_MASK  0x1FFF
-- 
2.7.4



[PATCH v2 net-next 18/21] net: usb: aqc111: Implement get/set_link_ksettings callbacks

2018-11-13 Thread Igor Russkikh
From: Dmitry Bezrukov 

Signed-off-by: Dmitry Bezrukov 
Signed-off-by: Igor Russkikh 
---
 drivers/net/usb/aqc111.c | 124 +++
 1 file changed, 124 insertions(+)

diff --git a/drivers/net/usb/aqc111.c b/drivers/net/usb/aqc111.c
index b3160b0320eb..80fedf2ab2dd 100644
--- a/drivers/net/usb/aqc111.c
+++ b/drivers/net/usb/aqc111.c
@@ -209,6 +209,85 @@ static void aqc111_get_drvinfo(struct net_device *net,
info->regdump_len = 0x00;
 }
 
+static void aqc111_speed_to_link_mode(u32 speed,
+ struct ethtool_link_ksettings *elk)
+{
+   switch (speed) {
+   case SPEED_5000:
+   ethtool_link_ksettings_add_link_mode(elk, advertising,
+5000baseT_Full);
+   break;
+   case SPEED_2500:
+   ethtool_link_ksettings_add_link_mode(elk, advertising,
+2500baseT_Full);
+   break;
+   case SPEED_1000:
+   ethtool_link_ksettings_add_link_mode(elk, advertising,
+1000baseT_Full);
+   break;
+   case SPEED_100:
+   ethtool_link_ksettings_add_link_mode(elk, advertising,
+100baseT_Full);
+   break;
+   }
+}
+
+static int aqc111_get_link_ksettings(struct net_device *net,
+struct ethtool_link_ksettings *elk)
+{
+   struct usbnet *dev = netdev_priv(net);
+   struct aqc111_data *aqc111_data = dev->driver_priv;
+   enum usb_device_speed usb_speed = dev->udev->speed;
+   u32 speed = SPEED_UNKNOWN;
+
+   ethtool_link_ksettings_zero_link_mode(elk, supported);
+   ethtool_link_ksettings_add_link_mode(elk, supported,
+100baseT_Full);
+   ethtool_link_ksettings_add_link_mode(elk, supported,
+1000baseT_Full);
+   if (usb_speed == USB_SPEED_SUPER) {
+   ethtool_link_ksettings_add_link_mode(elk, supported,
+2500baseT_Full);
+   ethtool_link_ksettings_add_link_mode(elk, supported,
+5000baseT_Full);
+   }
+   ethtool_link_ksettings_add_link_mode(elk, supported, TP);
+   ethtool_link_ksettings_add_link_mode(elk, supported, Autoneg);
+
+   elk->base.port = PORT_TP;
+   elk->base.transceiver = XCVR_INTERNAL;
+
+   elk->base.mdio_support = 0x00; /*Not supported*/
+
+   if (aqc111_data->autoneg)
+   bitmap_copy(elk->link_modes.advertising,
+   elk->link_modes.supported,
+   __ETHTOOL_LINK_MODE_MASK_NBITS);
+   else
+   aqc111_speed_to_link_mode(aqc111_data->advertised_speed, elk);
+
+   elk->base.autoneg = aqc111_data->autoneg;
+
+   switch (aqc111_data->link_speed) {
+   case AQ_INT_SPEED_5G:
+   speed = SPEED_5000;
+   break;
+   case AQ_INT_SPEED_2_5G:
+   speed = SPEED_2500;
+   break;
+   case AQ_INT_SPEED_1G:
+   speed = SPEED_1000;
+   break;
+   case AQ_INT_SPEED_100M:
+   speed = SPEED_100;
+   break;
+   }
+   elk->base.duplex = DUPLEX_FULL;
+   elk->base.speed = speed;
+
+   return 0;
+}
+
 static void aqc111_set_phy_speed_fw_iface(struct usbnet *dev,
  struct aqc111_data *aqc111_data)
 {
@@ -325,11 +404,56 @@ static void aqc111_set_phy_speed(struct usbnet *dev, u8 
autoneg, u16 speed)
aqc111_set_phy_speed_fw_iface(dev, aqc111_data);
 }
 
+static int aqc111_set_link_ksettings(struct net_device *net,
+const struct ethtool_link_ksettings *elk)
+{
+   struct usbnet *dev = netdev_priv(net);
+   struct aqc111_data *aqc111_data = dev->driver_priv;
+   enum usb_device_speed usb_speed = dev->udev->speed;
+   u8 autoneg = elk->base.autoneg;
+   u32 speed = elk->base.speed;
+
+   if (autoneg == AUTONEG_ENABLE) {
+   if (aqc111_data->autoneg != AUTONEG_ENABLE) {
+   aqc111_data->autoneg = AUTONEG_ENABLE;
+   aqc111_data->advertised_speed =
+   (usb_speed == USB_SPEED_SUPER) ?
+SPEED_5000 : SPEED_1000;
+   aqc111_set_phy_speed(dev, aqc111_data->autoneg,
+aqc111_data->advertised_speed);
+   }
+   } else {
+   if (speed != SPEED_100 &&
+   speed != SPEED_1000 &&
+   speed != SPEED_2500 &&
+   speed != SPEED_5000 &&
+   speed != SPEED_UNKNOWN)
+   

[PATCH v2 net-next 08/21] net: usb: aqc111: Implement TX data path

2018-11-13 Thread Igor Russkikh
From: Dmitry Bezrukov 

Signed-off-by: Dmitry Bezrukov 
Signed-off-by: Igor Russkikh 
---
 drivers/net/usb/aqc111.c | 72 
 drivers/net/usb/aqc111.h |  8 ++
 2 files changed, 80 insertions(+)

diff --git a/drivers/net/usb/aqc111.c b/drivers/net/usb/aqc111.c
index 15b86dee7bca..b630a8342ef2 100644
--- a/drivers/net/usb/aqc111.c
+++ b/drivers/net/usb/aqc111.c
@@ -302,6 +302,9 @@ static int aqc111_set_mac_addr(struct net_device *net, void 
*p)
 static const struct net_device_ops aqc111_netdev_ops = {
.ndo_open   = usbnet_open,
.ndo_stop   = usbnet_stop,
+   .ndo_start_xmit = usbnet_start_xmit,
+   .ndo_tx_timeout = usbnet_tx_timeout,
+   .ndo_get_stats64= usbnet_get_stats64,
.ndo_set_mac_address= aqc111_set_mac_addr,
.ndo_validate_addr  = eth_validate_addr,
 };
@@ -372,8 +375,19 @@ static int aqc111_bind(struct usbnet *dev, struct 
usb_interface *intf)
goto out;
 
ether_addr_copy(dev->net->dev_addr, dev->net->perm_addr);
+
+   /* Set TX needed headroom & tailroom */
+   dev->net->needed_headroom += sizeof(u64);
+   dev->net->needed_tailroom += sizeof(u64);
+
dev->net->netdev_ops = &aqc111_netdev_ops;
 
+   if (usb_device_no_sg_constraint(dev->udev))
+   dev->can_dma_sg = 1;
+
+   dev->net->hw_features |= AQ_SUPPORT_HW_FEATURE;
+   dev->net->features |= AQ_SUPPORT_FEATURE;
+
aqc111_read_fw_version(dev, aqc111_data);
aqc111_data->autoneg = AUTONEG_ENABLE;
aqc111_data->advertised_speed = (usb_speed == USB_SPEED_SUPER) ?
@@ -603,6 +617,12 @@ static int aqc111_reset(struct usbnet *dev)
u16 reg16 = 0;
u8 reg8 = 0;
 
+   if (usb_device_no_sg_constraint(dev->udev))
+   dev->can_dma_sg = 1;
+
+   dev->net->hw_features |= AQ_SUPPORT_HW_FEATURE;
+   dev->net->features |= AQ_SUPPORT_FEATURE;
+
/* Power up ethernet PHY */
aqc111_data->phy_cfg = AQ_PHY_POWER_EN;
if (aqc111_data->dpa) {
@@ -679,6 +699,55 @@ static int aqc111_stop(struct usbnet *dev)
return 0;
 }
 
+static struct sk_buff *aqc111_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
+  gfp_t flags)
+{
+   int frame_size = dev->maxpacket;
+   struct sk_buff *new_skb = NULL;
+   int padding_size = 0;
+   int headroom = 0;
+   int tailroom = 0;
+   u64 tx_desc = 0;
+
+   /*Length of actual data*/
+   tx_desc |= skb->len & AQ_TX_DESC_LEN_MASK;
+
+   headroom = (skb->len + sizeof(tx_desc)) % 8;
+   if (headroom != 0)
+   padding_size = 8 - headroom;
+
+   if (((skb->len + sizeof(tx_desc) + padding_size) % frame_size) == 0) {
+   padding_size += 8;
+   tx_desc |= AQ_TX_DESC_DROP_PADD;
+   }
+
+   if (!dev->can_dma_sg && (dev->net->features & NETIF_F_SG) &&
+   skb_linearize(skb))
+   return NULL;
+
+   headroom = skb_headroom(skb);
+   tailroom = skb_tailroom(skb);
+
+   if (!(headroom >= sizeof(tx_desc) && tailroom >= padding_size)) {
+   new_skb = skb_copy_expand(skb, sizeof(tx_desc),
+ padding_size, flags);
+   dev_kfree_skb_any(skb);
+   skb = new_skb;
+   if (!skb)
+   return NULL;
+   }
+   if (padding_size != 0)
+   skb_put(skb, padding_size);
+   /* Copy TX header */
+   skb_push(skb, sizeof(tx_desc));
+   cpu_to_le64s(&tx_desc);
+   skb_copy_to_linear_data(skb, &tx_desc, sizeof(tx_desc));
+
+   usbnet_set_skb_tx_stats(skb, 1, 0);
+
+   return skb;
+}
+
 static const struct driver_info aqc111_info = {
.description= "Aquantia AQtion USB to 5GbE Controller",
.bind   = aqc111_bind,
@@ -687,6 +756,9 @@ static const struct driver_info aqc111_info = {
.link_reset = aqc111_link_reset,
.reset  = aqc111_reset,
.stop   = aqc111_stop,
+   .flags  = FLAG_ETHER | FLAG_FRAMING_AX |
+ FLAG_AVOID_UNLINK_URBS | FLAG_MULTI_PACKET,
+   .tx_fixup   = aqc111_tx_fixup,
 };
 
 #define AQC111_USB_ETH_DEV(vid, pid, table) \
diff --git a/drivers/net/usb/aqc111.h b/drivers/net/usb/aqc111.h
index a6359ff759cd..a3d9d7dde240 100644
--- a/drivers/net/usb/aqc111.h
+++ b/drivers/net/usb/aqc111.h
@@ -60,6 +60,10 @@
 #define AQ_USB_PHY_SET_TIMEOUT 1
 #define AQ_USB_SET_TIMEOUT 4000
 
+/* Feature. /
+#define AQ_SUPPORT_FEATURE (NETIF_F_SG)
+#define AQ_SUPPORT_HW_FEATURE  (NETIF_F_SG)
+
 /* SFR Reg. /
 
 #define SFR_GENERAL_STATUS 0x03
@@ -192,6 +196,10 @@ struct aqc111_data {
 #define AQ_INT_SPEED_1G0x0011
 #define AQ_INT_SPEED_10

[PATCH v2 net-next 07/21] net: usb: aqc111: Add support for getting and setting of MAC address

2018-11-13 Thread Igor Russkikh
From: Dmitry Bezrukov 

Signed-off-by: Dmitry Bezrukov 
Signed-off-by: Igor Russkikh 
---
 drivers/net/usb/aqc111.c | 47 +++
 drivers/net/usb/aqc111.h |  1 +
 2 files changed, 48 insertions(+)

diff --git a/drivers/net/usb/aqc111.c b/drivers/net/usb/aqc111.c
index 2b78b5d7d29b..15b86dee7bca 100644
--- a/drivers/net/usb/aqc111.c
+++ b/drivers/net/usb/aqc111.c
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -284,11 +285,43 @@ static void aqc111_set_phy_speed(struct usbnet *dev, u8 
autoneg, u16 speed)
aqc111_set_phy_speed_fw_iface(dev, aqc111_data);
 }
 
+static int aqc111_set_mac_addr(struct net_device *net, void *p)
+{
+   struct usbnet *dev = netdev_priv(net);
+   int ret = 0;
+
+   ret = eth_mac_addr(net, p);
+   if (ret < 0)
+   return ret;
+
+   /* Set the MAC address */
+   return aqc111_write_cmd(dev, AQ_ACCESS_MAC, SFR_NODE_ID, ETH_ALEN,
+   ETH_ALEN, net->dev_addr);
+}
+
 static const struct net_device_ops aqc111_netdev_ops = {
.ndo_open   = usbnet_open,
.ndo_stop   = usbnet_stop,
+   .ndo_set_mac_address= aqc111_set_mac_addr,
+   .ndo_validate_addr  = eth_validate_addr,
 };
 
+static int aqc111_read_perm_mac(struct usbnet *dev)
+{
+   u8 buf[ETH_ALEN];
+   int ret;
+
+   ret = aqc111_read_cmd(dev, AQ_FLASH_PARAMETERS, 0, 0, ETH_ALEN, buf);
+   if (ret < 0)
+   goto out;
+
+   ether_addr_copy(dev->net->perm_addr, buf);
+
+   return 0;
+out:
+   return ret;
+}
+
 static void aqc111_read_fw_version(struct usbnet *dev,
   struct aqc111_data *aqc111_data)
 {
@@ -333,6 +366,12 @@ static int aqc111_bind(struct usbnet *dev, struct 
usb_interface *intf)
/* store aqc111_data pointer in device data field */
dev->driver_priv = aqc111_data;
 
+   /* Init the MAC address */
+   ret = aqc111_read_perm_mac(dev);
+   if (ret)
+   goto out;
+
+   ether_addr_copy(dev->net->dev_addr, dev->net->perm_addr);
dev->net->netdev_ops = &aqc111_netdev_ops;
 
aqc111_read_fw_version(dev, aqc111_data);
@@ -341,6 +380,10 @@ static int aqc111_bind(struct usbnet *dev, struct 
usb_interface *intf)
 SPEED_5000 : SPEED_1000;
 
return 0;
+
+out:
+   kfree(aqc111_data);
+   return ret;
 }
 
 static void aqc111_unbind(struct usbnet *dev, struct usb_interface *intf)
@@ -582,6 +625,10 @@ static int aqc111_reset(struct usbnet *dev)
   &aqc111_data->phy_cfg);
}
 
+   /* Set the MAC address */
+   aqc111_write_cmd(dev, AQ_ACCESS_MAC, SFR_NODE_ID, ETH_ALEN,
+ETH_ALEN, dev->net->dev_addr);
+
reg8 = 0xFF;
aqc111_write_cmd(dev, AQ_ACCESS_MAC, SFR_BM_INT_MASK, 1, 1, ®8);
 
diff --git a/drivers/net/usb/aqc111.h b/drivers/net/usb/aqc111.h
index fd49a43e6d93..a6359ff759cd 100644
--- a/drivers/net/usb/aqc111.h
+++ b/drivers/net/usb/aqc111.h
@@ -11,6 +11,7 @@
 #define __LINUX_USBNET_AQC111_H
 
 #define AQ_ACCESS_MAC  0x01
+#define AQ_FLASH_PARAMETERS0x20
 #define AQ_PHY_POWER   0x31
 #define AQ_PHY_CMD 0x32
 #define AQ_PHY_OPS 0x61
-- 
2.7.4



[PATCH v2 net-next 12/21] net: usb: aqc111: Add support for enable/disable checksum offload

2018-11-13 Thread Igor Russkikh
From: Dmitry Bezrukov 

Signed-off-by: Dmitry Bezrukov 
Signed-off-by: Igor Russkikh 
---
 drivers/net/usb/aqc111.c | 45 -
 drivers/net/usb/aqc111.h |  1 +
 2 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/drivers/net/usb/aqc111.c b/drivers/net/usb/aqc111.c
index e197824f96f1..891d6832b87c 100644
--- a/drivers/net/usb/aqc111.c
+++ b/drivers/net/usb/aqc111.c
@@ -341,6 +341,46 @@ static int aqc111_set_mac_addr(struct net_device *net, 
void *p)
ETH_ALEN, net->dev_addr);
 }
 
+static int aqc111_set_features(struct net_device *net,
+  netdev_features_t features)
+{
+   struct usbnet *dev = netdev_priv(net);
+   struct aqc111_data *aqc111_data = dev->driver_priv;
+   netdev_features_t changed = net->features ^ features;
+   u8 reg8 = 0;
+
+   if (changed & NETIF_F_IP_CSUM) {
+   aqc111_read_cmd(dev, AQ_ACCESS_MAC, SFR_TXCOE_CTL, 1, 1, ®8);
+   reg8 ^= SFR_TXCOE_TCP | SFR_TXCOE_UDP;
+   aqc111_write_cmd(dev, AQ_ACCESS_MAC, SFR_TXCOE_CTL,
+1, 1, ®8);
+   }
+
+   if (changed & NETIF_F_IPV6_CSUM) {
+   aqc111_read_cmd(dev, AQ_ACCESS_MAC, SFR_TXCOE_CTL, 1, 1, ®8);
+   reg8 ^= SFR_TXCOE_TCPV6 | SFR_TXCOE_UDPV6;
+   aqc111_write_cmd(dev, AQ_ACCESS_MAC, SFR_TXCOE_CTL,
+1, 1, ®8);
+   }
+
+   if (changed & NETIF_F_RXCSUM) {
+   aqc111_read_cmd(dev, AQ_ACCESS_MAC, SFR_RXCOE_CTL, 1, 1, ®8);
+   if (features & NETIF_F_RXCSUM) {
+   aqc111_data->rx_checksum = 1;
+   reg8 &= ~(SFR_RXCOE_IP | SFR_RXCOE_TCP | SFR_RXCOE_UDP |
+ SFR_RXCOE_TCPV6 | SFR_RXCOE_UDPV6);
+   } else {
+   aqc111_data->rx_checksum = 0;
+   reg8 |= SFR_RXCOE_IP | SFR_RXCOE_TCP | SFR_RXCOE_UDP |
+   SFR_RXCOE_TCPV6 | SFR_RXCOE_UDPV6;
+   }
+
+   aqc111_write_cmd(dev, AQ_ACCESS_MAC, SFR_RXCOE_CTL,
+1, 1, ®8);
+   }
+   return 0;
+}
+
 static const struct net_device_ops aqc111_netdev_ops = {
.ndo_open   = usbnet_open,
.ndo_stop   = usbnet_stop,
@@ -350,6 +390,7 @@ static const struct net_device_ops aqc111_netdev_ops = {
.ndo_change_mtu = aqc111_change_mtu,
.ndo_set_mac_address= aqc111_set_mac_addr,
.ndo_validate_addr  = eth_validate_addr,
+   .ndo_set_features   = aqc111_set_features,
 };
 
 static int aqc111_read_perm_mac(struct usbnet *dev)
@@ -801,6 +842,7 @@ static void aqc111_rx_checksum(struct sk_buff *skb, u64 
*pkt_desc)
 
 static int aqc111_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
 {
+   struct aqc111_data *aqc111_data = dev->driver_priv;
struct sk_buff *new_skb = NULL;
u32 pkt_total_offset = 0;
u32 start_of_descs = 0;
@@ -877,7 +919,8 @@ static int aqc111_rx_fixup(struct usbnet *dev, struct 
sk_buff *skb)
skb_set_tail_pointer(new_skb, new_skb->len);
 
new_skb->truesize = new_skb->len + sizeof(struct sk_buff);
-   aqc111_rx_checksum(new_skb, pkt_desc);
+   if (aqc111_data->rx_checksum)
+   aqc111_rx_checksum(new_skb, pkt_desc);
 
usbnet_skb_return(dev, new_skb);
if (pkt_count == 0)
diff --git a/drivers/net/usb/aqc111.h b/drivers/net/usb/aqc111.h
index 20637fd58be3..477815f8b7de 100644
--- a/drivers/net/usb/aqc111.h
+++ b/drivers/net/usb/aqc111.h
@@ -180,6 +180,7 @@
 
/**/
 
 struct aqc111_data {
+   u8 rx_checksum;
u8 link_speed;
u8 link;
u8 autoneg;
-- 
2.7.4



Re: WARNING in usb_submit_urb (4)

2018-11-13 Thread Alan Stern
On Mon, 12 Nov 2018, syzbot wrote:

> syzbot has found a reproducer for the following crash on:
> 
> HEAD commit:e12e00e388de Merge tag 'kbuild-fixes-v4.20' of git://git.k..
> git tree:   upstream
> console output: https://syzkaller.appspot.com/x/log.txt?x=100e4ef540
> kernel config:  https://syzkaller.appspot.com/x/.config?x=8f215f21f041a0d7
> dashboard link: https://syzkaller.appspot.com/bug?extid=7634edaea4d0b341c625
> compiler:   gcc (GCC) 8.0.1 20180413 (experimental)
> syz repro:  https://syzkaller.appspot.com/x/repro.syz?x=11ce6fbd40
> 
> IMPORTANT: if you fix the bug, please add the following tag to the commit:
> Reported-by: syzbot+7634edaea4d0b341c...@syzkaller.appspotmail.com

I tried reproducing this bug on my own system, following the 
instructions at

https://github.com/google/syzkaller/blob/master/docs/executing_syzkaller_programs.md

The reproducer failed to run properly.  It produced the following 
output:


$ ./syz-execprog -cover=0 -threaded=1 -repeat=1 -procs=4 /tmp/repro.syz 
2018/11/13 15:29:32 parsed 1 programs
2018/11/13 15:29:32 executed programs: 0
2018/11/13 15:29:32 result: failed=false hanged=false err=executor 3: failed: 
tun: ioctl(TUNSETIFF) failed (errno 1)
loop failed (errno 0)


tun: ioctl(TUNSETIFF) failed (errno 1)
loop failed (errno 0)


The system is Fedora 28 running the 4.18.16-200.fc28.x86_64 kernel.  
What should I do to investigate further?

Alan Stern



Re: [PATCH v2 net-next 18/21] net: usb: aqc111: Implement get/set_link_ksettings callbacks

2018-11-13 Thread Andrew Lunn
On Tue, Nov 13, 2018 at 02:45:13PM +, Igor Russkikh wrote:
> +static int aqc111_get_link_ksettings(struct net_device *net,
> +  struct ethtool_link_ksettings *elk)
> +{
> + struct usbnet *dev = netdev_priv(net);
> + struct aqc111_data *aqc111_data = dev->driver_priv;
> + enum usb_device_speed usb_speed = dev->udev->speed;
> + u32 speed = SPEED_UNKNOWN;
> +
> + ethtool_link_ksettings_zero_link_mode(elk, supported);
> + ethtool_link_ksettings_add_link_mode(elk, supported,
> +  100baseT_Full);
> + ethtool_link_ksettings_add_link_mode(elk, supported,
> +  1000baseT_Full);
> + if (usb_speed == USB_SPEED_SUPER) {
> + ethtool_link_ksettings_add_link_mode(elk, supported,
> +  2500baseT_Full);
> + ethtool_link_ksettings_add_link_mode(elk, supported,
> +  5000baseT_Full);
> + }

Hi Igor

We discussed this with the first version of the patches. I think you
should add a comment explaining why 2.5G and 5G is disabled unless
Super speed is available.

> + if (aqc111_data->autoneg)
> + bitmap_copy(elk->link_modes.advertising,
> + elk->link_modes.supported,
> + __ETHTOOL_LINK_MODE_MASK_NBITS);

linkmode_copy(). It is quite new, so you probably don't know about it.

 Andrew


Re: [PATCH v2 net-next 06/21] net: usb: aqc111: Introduce link management

2018-11-13 Thread Andrew Lunn
On Tue, Nov 13, 2018 at 02:44:45PM +, Igor Russkikh wrote:
> From: Dmitry Bezrukov 
> 
> Add full hardware initialization sequence and link configuration logic

Hi Igor

I'm still not convinced the PHY driver should be embedded in the MAC
driver, rather than using phylink.

If i remember correctly, it was because the MAC is involved in
determining if the link is up? That is nothing new. phylink expects
this. The MAC driver should call phylink_mac_change() when the MACs
SERDES goes up/down.

   Andrew


Re: [PATCH v2 net-next 19/21] net: usb: aqc111: Add support for wake on LAN by MAGIC packet

2018-11-13 Thread Andrew Lunn
> +static int aqc111_suspend(struct usb_interface *intf, pm_message_t message)
> +{

> +
> + if (aqc111_data->dpa) {
> + aqc111_set_phy_speed(dev, AUTONEG_ENABLE, SPEED_100);

So this is better, you leave auto-neg enabled. But you really should
be taking the link partners capabilities into account.

   Andrew


Re: [PATCH V3 4/6] usb: ohci-platform: Add support for Broadcom STB SoC's

2018-11-13 Thread Alan Cooper
On Mon, Nov 12, 2018 at 6:37 PM Rob Herring  wrote:
>
> On Wed, Nov 07, 2018 at 10:11:59AM -0800, Florian Fainelli wrote:
> > On 11/7/2018 9:40 AM, Al Cooper wrote:
> > > On 11/7/18 12:29 PM, Florian Fainelli wrote:
> > >> On 11/7/18 8:27 AM, Alan Stern wrote:
> > >>> On Wed, 7 Nov 2018, Al Cooper wrote:
> > >>>
> >  On 11/7/18 10:23 AM, Alan Stern wrote:
> > > On Tue, 6 Nov 2018, Florian Fainelli wrote:
> > >
> > >> On 11/6/18 1:40 PM, Al Cooper wrote:
> > >>> On 11/6/18 11:08 AM, Alan Stern wrote:
> >  On Mon, 5 Nov 2018, Al Cooper wrote:
> > 
> > > Add support for Broadcom STB SoC's to the ohci platform driver.
> > >
> > > Signed-off-by: Al Cooper 
> > > ---
> > 
> > > @@ -177,6 +189,8 @@ static int ohci_platform_probe(struct
> > > platform_device *dev)
> > > ohci->flags |= OHCI_QUIRK_FRAME_NO;
> > > if (pdata->num_ports)
> > > ohci->num_ports = pdata->num_ports;
> > > +if (pdata->suspend_without_phy_exit)
> > > +hcd->suspend_without_phy_exit = 1;
> > 
> >  Sorry if I missed this in the earlier discussions...  Is there any
> >  possibility of adding a DT binding that could express this
> >  requirement,
> >  instead of putting it in the platform data?
> > 
> >  Alan Stern
> > 
> > >>>
> > >>> Alan,
> > >>>
> > >>> That was my original approach but internal review suggested that
> > >>> I use
> > >>> pdata instead. Below is my original patch for:
> > >>
> > >> And the reason for that suggestion was really because it was
> > >> percevied
> > >> as encoding a driver behavior as a Device Tree property as opposed to
> > >> describing something that was inherently and strictly a hardware
> > >> behavior (therefore suitable for Device Tree).
> > >
> > > Right.  The best way to approach this problem is to identify and
> > > characterize the hardware behavior which makes this override
> > > necessary.
> > > Then _that_ can be added to DT, since it will be a property of the
> > > hardware rather than of the driver.
> > >
> > >>> Add the ability to skip calling the PHY's exit routine on suspend
> > >>> and the PHY's init routine on resume. This is to handle a USB PHY
> > >>> that should have it's power_off function called on suspend but
> > >>> cannot
> > >>> have it's exit function called because on exit it will disable the
> > >>> PHY to the point where register accesses to the Host Controllers
> > >>> using the PHY will be disabled and the host drivers will crash.
> > >
> > > What's special about this PHY?  Why does the exit function mess the
> > > PHY
> > > up?  Or to put it another way, why doesn't the exit function mess up
> > > other PHYs in the same way?
> > >
> > > For that matter, can we change the code so that suspend doesn't call
> > > the exit function for _any_ PHY?  Will just calling the power_off
> > > function be good enough?  If not, then why not?
> > >
> > > Alan Stern
> > >
> > 
> >  In our USB hardware the USB PHY supplies a clock for the EHCI/OHCI and
> >  XHCI host controllers and if the PHY is totally shut down the EHCI,
> >  OHCI
> >  and XHCI registers will cause an exception if accessed and cause the
> >  EHCI, OHCI and XHCI drivers to crash. There is always talk of fixing
> >  this in the hardware by adding an aux clock that will takeover when the
> >  PHY clock is shut down, but this hasn't happened yet. It seems like
> >  "exit on suspend" still makes sense on systems that don't have this
> >  problem (additional power savings?) so removing the exit on suspend for
> >  all systems is not a good idea.
> > >>>
> > >>> Then in theory you should be able to add a Device Tree property which
> > >>> says that the PHY provides a clock for the USB host controller.  That
> > >>> is strictly a property of the hardware; it has nothing to do with the
> > >>> driver.  Therefore it is appropriate for DT.
> > >>
> > >> The very compatible string that is being allocated/defined for this
> > >> controller carries that information already, that is, if you probe a
> > >> "brcm,bcm7445-ohci" compatible then that means the controller has a
> > >> dependency on the PHY to supply its clock.
> > >>
> > >> Adding a property vs. keying on the compatible string makes sense if you
> > >> know there is at least a second consumer of that property (unless we
> > >> make it a broadcom specific property, in which case, it really is
> > >> redundant with the compatible string).
> > >>
> > >> Anyway, my grudge with that property was the name chosen initially,
> > >> which included an action to be performed by an implementation as opposed
> > >> to something purely descriptive. E.g: 'phy-suppl

Re: [PATCH v2] usb: dwc2: host: use hrtimer for NAK retries

2018-11-13 Thread Doug Anderson
Hi,

On Sun, Sep 9, 2018 at 9:24 PM Terin Stock  wrote:
>
> Modify the wait delay utilize the high resolution timer API to allow for
> more precisely scheduled callbacks.
>
> A previous commit added a 1ms retry delay after multiple consecutive
> NAKed transactions using jiffies. On systems with a low timer interrupt
> frequency, this delay may be significantly longer than specified,
> resulting in misbehavior with some USB devices.
>
> This scenario was reached on a Raspberry Pi 3B with a Macally FDD-USB
> floppy drive (identified as 0424:0fdc Standard Microsystems Corp.
> Floppy, based on the USB97CFDC USB FDC). With the relay delay, the drive
> would be unable to mount a disk, replying with NAKs until the device was
> reset.
>
> Using ktime, the delta between starting the timer (in dwc2_hcd_qh_add)
> and the callback function can be determined. With the original delay
> implementation, this value was consistently approximately 12ms. (output
> in us).
>
> -0 [000] ..s.  1600.559974: dwc2_wait_timer_fn: wait_timer 
> delta: 11976
> -0 [000] ..s.  1600.571974: dwc2_wait_timer_fn: wait_timer 
> delta: 11977
> -0 [000] ..s.  1600.583974: dwc2_wait_timer_fn: wait_timer 
> delta: 11976
> -0 [000] ..s.  1600.595974: dwc2_wait_timer_fn: wait_timer 
> delta: 11977
>
> After converting the relay delay to using a higher resolution timer, the
> delay was much closer to 1ms.
>
> -0 [000] d.h.  1956.553017: dwc2_wait_timer_fn: wait_timer 
> delta: 1002
> -0 [000] d.h.  1956.554114: dwc2_wait_timer_fn: wait_timer 
> delta: 1002
> -0 [000] d.h.  1957.542660: dwc2_wait_timer_fn: wait_timer 
> delta: 1004
> -0 [000] d.h.  1957.543701: dwc2_wait_timer_fn: wait_timer 
> delta: 1002
>
> The floppy drive operates properly with delays up to approximately 5ms,
> and sends NAKs for any delays that are longer.
>
> Fixes: 38d2b5fb75c1 ("usb: dwc2: host: Don't retry NAKed transactions right 
> away")
> Signed-off-by: Terin Stock 
> ---
>  drivers/usb/dwc2/hcd.h   |2 +-
>  drivers/usb/dwc2/hcd_queue.c |   19 ---
>  2 files changed, 13 insertions(+), 8 deletions(-)

Reviewed-by: Douglas Anderson 
Cc: sta...@vger.kernel.org


Re: [PATCH v1 2/5] extcon: Return -EPROBE_DEFER when extcon device is not found

2018-11-13 Thread Chanwoo Choi
Hi Andy,

I was thinking about again to change from NULL to EPROBE_DEFER.

extcon_get_extcon_dev() function was almost called in the probe function.
But, this function might be called on other position instead of probe.

ENODEV is more correct error instead of EPROBE_DEFER.

Sorry. I'll withdraw my opinion related acked-by tag until we are clarifying it.

On 2018년 11월 12일 09:24, Chanwoo Choi wrote:
> Hi Andy,
> 
> On 2018년 11월 11일 03:10, Andy Shevchenko wrote:
>> All current users of extcon_get_extcon_dev() API considers
>> an extcon device a mandatory to appear. Thus, they all convert
>> NULL pointer to -EPROBE_DEFER error code.
>>
>> There is one more caller anticipated with the same requirements.
>>
>> To decrease a code duplication and a burden to the callers,
>> return -EPROBE_DEFER directly from extcon_get_extcon_dev().
>>
>> Signed-off-by: Andy Shevchenko 
>> ---
>>  drivers/extcon/extcon-axp288.c| 4 ++--
>>  drivers/extcon/extcon.c   | 2 +-
>>  drivers/power/supply/axp288_charger.c | 8 
>>  drivers/usb/phy/phy-omap-otg.c| 6 +++---
>>  drivers/usb/typec/tcpm/fusb302.c  | 4 ++--
>>  5 files changed, 12 insertions(+), 12 deletions(-)
> 
> Acked-by: Chanwoo Choi 
> 
> Best Regards,
> Chanwoo Choi
> 
>>
>> diff --git a/drivers/extcon/extcon-axp288.c b/drivers/extcon/extcon-axp288.c
>> index a983708b77a6..3472d3b756ed 100644
>> --- a/drivers/extcon/extcon-axp288.c
>> +++ b/drivers/extcon/extcon-axp288.c
>> @@ -360,8 +360,8 @@ static int axp288_extcon_probe(struct platform_device 
>> *pdev)
>>  name = acpi_dev_get_first_match_name("INT3496", NULL, -1);
>>  if (name) {
>>  info->id_extcon = extcon_get_extcon_dev(name);
>> -if (!info->id_extcon)
>> -return -EPROBE_DEFER;
>> +if (IS_ERR(info->id_extcon))
>> +return PTR_ERR(info->id_extcon);
>>  
>>  dev_info(dev, "controlling USB role\n");
>>  } else {
>> diff --git a/drivers/extcon/extcon.c b/drivers/extcon/extcon.c
>> index 5ab0498be652..2bd0f2f33f05 100644
>> --- a/drivers/extcon/extcon.c
>> +++ b/drivers/extcon/extcon.c
>> @@ -884,7 +884,7 @@ struct extcon_dev *extcon_get_extcon_dev(const char 
>> *extcon_name)
>>  if (!strcmp(sd->name, extcon_name))
>>  goto out;
>>  }
>> -sd = NULL;
>> +sd = ERR_PTR(-EPROBE_DEFER);


(snip)

-- 
Best Regards,
Chanwoo Choi
Samsung Electronics


Re: [PATCH v1 1/5] drivercore: Revert "deferral race condition fix"

2018-11-13 Thread Mark Brown
On Mon, Nov 12, 2018 at 06:11:26PM +0200, Peter Ujfalusi wrote:

> if we revert the commit then the original issue will re-surfaces. afaik
> it was not only audio which hit the 'last driver to be probed from the
> deferred list would never probe, unless we provoke the kernel to load
> additional module, or remove/reload the module' issue.

Right, aren't we just going to be swapping one bug for another?

> Do I understand correctly that in your case you have two modules
> (dwc3-pci and extcon-intel-mrfld) in a deferred probe loop, iow both of
> the drivers returns -EPROBE_DEFER and they just spin?

> If both is deferring, how this supposed to work?

I'm struggling to follow the original explanation too :(


signature.asc
Description: PGP signature


RE: scsi_set_medium_removal timeout issue

2018-11-13 Thread Zengtao (B)
Hi Alan:

>-Original Message-
>From: Alan Stern [mailto:st...@rowland.harvard.edu]
>Sent: Monday, November 12, 2018 11:33 PM
>To: Zengtao (B) 
>Cc: j...@linux.vnet.ibm.com; martin.peter...@oracle.com;
>gre...@linuxfoundation.org; linux-s...@vger.kernel.org;
>linux-ker...@vger.kernel.org; linux-usb@vger.kernel.org;
>usb-stor...@lists.one-eyed-alien.net
>Subject: RE: scsi_set_medium_removal timeout issue
>
>On Mon, 12 Nov 2018, Zengtao (B) wrote:
>
>> >> >Something is wrong here.  Before sending PREVENT-ALLOW
>MEDIUM
>> >> >REMOVAL, the host should issue SYNCHRONIZE CACHE.  This will
>force
>> >> >fsg_lun_fsync_sub to run, and the host should allow a long timeout
>> >> >for this command.  Then when PREVENT-ALLOW MEDIUM
>REMOVAL
>> >is sent,
>> >> >nothing will need to be flushed.
>> >> >
>> >>
>> >> Definitely, I haven't seen the SYNCHRONIZE CACHE from the host, it
>> >> directly issued the PREVENT-ALLOW MEDIUM REMOVAL, so maybe
>> >something
>> >> wrong with the scsi layer or something wrong with the mass storage
>> >class driver?
>> >
>> >Or it could be something else.  Can you please post the dmesg log
>> >from the host, showing what happens when the device is first plugged
>in?
>> >
>>
>> I have enabled the SCSI log for the host, please refer to the attachment.
>
>The log you attached was incomplete -- it was missing some commands

I just enabled the scsi log in the middle of the umount operation, otherwise I 
can't
reproduce the issue when the scsi log is enabled.

>from the beginning.  In any case, it wasn't what I wanted.  I asked you to
>post the dmesg log, not the SCSI log.

Please refer to the new attachment for dmesg log.

Thanks 
Zengtao 

~ # dmesg 
Booting Linux on physical CPU 0x0
Linux version 4.9.37 (lpcheng@osdrv) (gcc version 6.3.0 (HC&C 
V100R002C00B021_20180917) ) #5 SMP Mon Nov 12 19:35:04 HKT 2018
CPU: ARMv7 Processor [410fd034] revision 4 (ARMv7), cr=10c5383d
CPU: div instructions available: patching division code
CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
OF: fdt:Machine model: Hisilicon Hi3519AV100 SMP Board
cma: dma_contiguous_reserve(limit )
cma: dma_contiguous_reserve: reserving 16 MiB for global area
cma: cma_declare_contiguous(size 0x0100, base 0x, limit 0x 
alignment 0x)
cma: Reserved 16 MiB at 0x3100
Memory policy: Data cache writealloc
On node 0 totalpages: 65536
free_area_init_node: node 0, pgdat c092d580, node_mem_map cedf1000
  Normal zone: 512 pages used for memmap
  Normal zone: 0 pages reserved
  Normal zone: 65536 pages, LIFO batch:15
percpu: Embedded 13 pages/cpu @cedc6000 s22028 r8192 d23028 u53248
pcpu-alloc: s22028 r8192 d23028 u53248 alloc=13*4096
pcpu-alloc: [0] 0 [0] 1 
Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 65024
Kernel command line: mem=256M console=ttyAMA0,115200 clk_ignore_unused 
root=/dev/mtdblock2 rw rootfstype=yaffs2 
mtdparts=hinand:1M(boot),4M(kernel),60M(rootfs) nosmp
PID hash table entries: 1024 (order: 0, 4096 bytes)
Dentry cache hash table entries: 32768 (order: 5, 131072 bytes)
Inode-cache hash table entries: 16384 (order: 4, 65536 bytes)
Memory: 234544K/262144K available (5120K kernel code, 184K rwdata, 1368K 
rodata, 1024K init, 321K bss, 11216K reserved, 16384K cma-reserved, 0K highmem)
Virtual kernel memory layout:
vector  : 0x - 0x1000   (   4 kB)
fixmap  : 0xffc0 - 0xfff0   (3072 kB)
vmalloc : 0xd080 - 0xff80   ( 752 MB)
lowmem  : 0xc000 - 0xd000   ( 256 MB)
pkmap   : 0xbfe0 - 0xc000   (   2 MB)
modules : 0xbf00 - 0xbfe0   (  14 MB)
  .text : 0xc0008000 - 0xc060   (6112 kB)
  .init : 0xc080 - 0xc090   (1024 kB)
  .data : 0xc090 - 0xc092e180   ( 185 kB)
   .bss : 0xc093 - 0xc098072c   ( 322 kB)
SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=2, Nodes=1
Hierarchical RCU implementation.
Build-time adjustment of leaf fanout to 32.
RCU restricting CPUs from NR_CPUS=4 to nr_cpu_ids=2.
RCU: Adjusting geometry for rcu_fanout_leaf=32, nr_cpu_ids=2
NR_IRQS:16 nr_irqs:16 16
arm_arch_timer: Architected cp15 timer(s) running at 24.00MHz (phys).
clocksource: arch_sys_counter: mask: 0xff max_cycles: 0x588fe9dc0, 
max_idle_ns: 440795202592 ns
sched_clock: 56 bits at 24MHz, resolution 41ns, wraps every 4398046511097ns
Switching to timer-based delay loop, resolution 41ns
clocksource: hisp804: mask: 0x max_cycles: 0x, max_idle_ns: 
637086815595 ns
Console: colour dummy device 80x30
Calibrating delay loop (skipped), value calculated using timer frequency.. 
48.00 BogoMIPS (lpj=12)
pid_max: default: 32768 minimum: 301
Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
CPU: Testing write buffer coherency: ok
CPU0: thread -1, cpu 0, socket 0, mpidr 8000
Setting up static identity map for 0x2210 - 0x22100058
Brought up 1

Re: [PATCH v2 net-next 06/21] net: usb: aqc111: Introduce link management

2018-11-13 Thread Igor Russkikh
>>
>> Add full hardware initialization sequence and link configuration logic
> 
> Hi Igor
> 
> I'm still not convinced the PHY driver should be embedded in the MAC
> driver, rather than using phylink.
> 
> If i remember correctly, it was because the MAC is involved in
> determining if the link is up? That is nothing new. phylink expects
> this. The MAC driver should call phylink_mac_change() when the MACs
> SERDES goes up/down.

Hi Andrew,

I'm actually still in doubt as well on this matter.
Of course thats quite possible.

Here was my original comment:

> Thats again because of this product has tightly integrated MAC+Phy.
> MAC FW controls system interface and reports/alters link state
> as a joint state on copper and SIF (even in dpa direct phy mode).
> 
> We can't extract phy api into a standalone fully functional phylib therefore.
> Also as far as I know this particular phy is not available in the wild.

So the point is that MAC firmware is managing SERDES and system interface link.
Even if we cut out phy stuff into a separate phylink driver - that driver will
never be functional in standalone mode, without aqc111 mac driver.

It only may make sense from software decomposition perspective - to separate 
pieces of
phy code.

We'll discuss and reconsider this internally and will give you more comments,

Thanks,
  Igor


Re: [PATCH v2 net-next 18/21] net: usb: aqc111: Implement get/set_link_ksettings callbacks

2018-11-13 Thread Igor Russkikh

>> +if (usb_speed == USB_SPEED_SUPER) {
>> +ethtool_link_ksettings_add_link_mode(elk, supported,
>> + 2500baseT_Full);
>> +ethtool_link_ksettings_add_link_mode(elk, supported,
>> + 5000baseT_Full);
>> +}
> 
> Hi Igor
> 
> We discussed this with the first version of the patches. I think you
> should add a comment explaining why 2.5G and 5G is disabled unless
> Super speed is available.

Right, I've explained that to you but forgot to add a comment here.

>> +if (aqc111_data->autoneg)
>> +bitmap_copy(elk->link_modes.advertising,
>> +elk->link_modes.supported,
>> +__ETHTOOL_LINK_MODE_MASK_NBITS);
> 
> linkmode_copy(). It is quite new, so you probably don't know about it.

Ok,

Regards,
  Igor


Re: [PATCH v2 net-next 19/21] net: usb: aqc111: Add support for wake on LAN by MAGIC packet

2018-11-13 Thread Igor Russkikh

>> +
>> +if (aqc111_data->dpa) {
>> +aqc111_set_phy_speed(dev, AUTONEG_ENABLE, SPEED_100);
> 
> So this is better, you leave auto-neg enabled. But you really should
> be taking the link partners capabilities into account.

We've considered that, but then thought about the following case:

After such a sleep state where partner's capabilities were considered,
user may move with the unit and replug it into different link partner with
other, incompatible speed mask. That will anyway lead to wol link failure.

In that sense it may be better to just select the most widely available
100M low power speed and don't do any intelligence here?

Regards,
  Igor