Netdev List
 help / color / mirror / Atom feed
* [PATCH v2 net-next 04/21] net: usb: aqc111: Various callbacks implementation
From: Igor Russkikh @ 2018-11-13 14:44 UTC (permalink / raw)
  To: David S . Miller
  Cc: linux-usb@vger.kernel.org, netdev@vger.kernel.org,
	Dmitry Bezrukov, Igor Russkikh
In-Reply-To: <cover.1542119058.git.igor.russkikh@aquantia.com>

From: Dmitry Bezrukov <dmitry.bezrukov@aquantia.com>

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 <dmitry.bezrukov@aquantia.com>
Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com>
---
 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, &reg16);
+	reg16 = 0;
+	aqc111_write16_cmd_nopm(dev, AQ_ACCESS_MAC, SFR_PHYPWR_RSTCTL,
+				2, &reg16);
+}
+
+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, &reg8);
+
+	reg8 = 0x0;
+	aqc111_write_cmd(dev, AQ_ACCESS_MAC, SFR_SWP_CTRL, 1, 1, &reg8);
+
+	aqc111_read_cmd(dev, AQ_ACCESS_MAC, SFR_MONITOR_MODE, 1, 1, &reg8);
+	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, &reg8);
+
+	return 0;
+}
+
+static int aqc111_stop(struct usbnet *dev)
+{
+	u16 reg16 = 0;
+
+	aqc111_read16_cmd(dev, AQ_ACCESS_MAC, SFR_MEDIUM_STATUS_MODE,
+			  2, &reg16);
+	reg16 &= ~SFR_MEDIUM_RECEIVE_EN;
+	aqc111_write16_cmd(dev, AQ_ACCESS_MAC, SFR_MEDIUM_STATUS_MODE,
+			   2, &reg16);
+	reg16 = 0;
+	aqc111_write16_cmd(dev, AQ_ACCESS_MAC, SFR_RX_CTL, 2, &reg16);
+
+	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		10000
 #define AQ_USB_SET_TIMEOUT		4000
 
+/* SFR Reg. ********************************************/
+
+#define SFR_GENERAL_STATUS		0x03
+#define SFR_CHIP_STATUS			0x05
+#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_START		0x0080
+	#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_AMALL		0x0002
+	#define SFR_RX_CTL_PRO			0x0001
+	#define SFR_RX_CTL_STOP			0x0000
+#define SFR_INTER_PACKET_GAP_0		0x0D
+#define SFR_NODE_ID			0x10
+#define SFR_MULTI_FILTER_ARRY		0x16
+#define SFR_MEDIUM_STATUS_MODE		0x22
+	#define SFR_MEDIUM_XGMIIMODE		0x0001
+	#define SFR_MEDIUM_FULL_DUPLEX		0x0002
+	#define SFR_MEDIUM_RXFLOW_CTRLEN	0x0010
+	#define SFR_MEDIUM_TXFLOW_CTRLEN	0x0020
+	#define SFR_MEDIUM_JUMBO_EN		0x0040
+	#define SFR_MEDIUM_RECEIVE_EN		0x0100
+#define SFR_MONITOR_MODE		0x24
+	#define SFR_MONITOR_MODE_EPHYRW		0x01
+	#define SFR_MONITOR_MODE_RWLC		0x02
+	#define SFR_MONITOR_MODE_RWMP		0x04
+	#define SFR_MONITOR_MODE_RWWF		0x08
+	#define SFR_MONITOR_MODE_RW_FLAG	0x10
+	#define SFR_MONITOR_MODE_PMEPOL		0x20
+	#define SFR_MONITOR_MODE_PMETYPE	0x40
+#define SFR_PHYPWR_RSTCTL		0x26
+	#define SFR_PHYPWR_RSTCTL_BZ		0x0010
+	#define SFR_PHYPWR_RSTCTL_IPRL		0x0020
+#define SFR_VLAN_ID_ADDRESS		0x2A
+#define SFR_VLAN_ID_CONTROL		0x2B
+	#define SFR_VLAN_CONTROL_WE		0x0001
+	#define SFR_VLAN_CONTROL_RD		0x0002
+	#define SFR_VLAN_CONTROL_VSO		0x0010
+	#define SFR_VLAN_CONTROL_VFE		0x0020
+#define SFR_VLAN_ID_DATA0		0x2C
+#define SFR_VLAN_ID_DATA1		0x2D
+#define SFR_RX_BULKIN_QCTRL		0x2E
+	#define SFR_RX_BULKIN_QCTRL_TIME	0x01
+	#define SFR_RX_BULKIN_QCTRL_IFG		0x02
+	#define SFR_RX_BULKIN_QCTRL_SIZE	0x04
+#define SFR_RX_BULKIN_QTIMR_LOW		0x2F
+#define SFR_RX_BULKIN_QTIMR_HIGH	0x30
+#define SFR_RX_BULKIN_QSIZE		0x31
+#define SFR_RX_BULKIN_QIFG		0x32
+#define SFR_RXCOE_CTL			0x34
+	#define SFR_RXCOE_IP			0x01
+	#define SFR_RXCOE_TCP			0x02
+	#define SFR_RXCOE_UDP			0x04
+	#define SFR_RXCOE_ICMP			0x08
+	#define SFR_RXCOE_IGMP			0x10
+	#define SFR_RXCOE_TCPV6			0x20
+	#define SFR_RXCOE_UDPV6			0x40
+	#define SFR_RXCOE_ICMV6			0x80
+#define SFR_TXCOE_CTL			0x35
+	#define SFR_TXCOE_IP			0x01
+	#define SFR_TXCOE_TCP			0x02
+	#define SFR_TXCOE_UDP			0x04
+	#define SFR_TXCOE_ICMP			0x08
+	#define SFR_TXCOE_IGMP			0x10
+	#define SFR_TXCOE_TCPV6			0x20
+	#define SFR_TXCOE_UDPV6			0x40
+	#define SFR_TXCOE_ICMV6			0x80
+#define SFR_BM_INT_MASK			0x41
+#define SFR_BMRX_DMA_CONTROL		0x43
+	#define SFR_BMRX_DMA_EN			0x80
+#define SFR_BMTX_DMA_CONTROL		0x46
+#define SFR_PAUSE_WATERLVL_LOW		0x54
+#define SFR_PAUSE_WATERLVL_HIGH		0x55
+#define SFR_ARC_CTRL			0x9E
+#define SFR_SWP_CTRL			0xB1
+#define SFR_TX_PAUSE_RESEND_T		0xB2
+#define SFR_ETH_MAC_PATH		0xB7
+	#define SFR_RX_PATH_READY		0x01
+#define SFR_BULK_OUT_CTRL		0xB9
+	#define SFR_BULK_OUT_FLUSH_EN		0x01
+	#define SFR_BULK_OUT_EFF_EN		0x02
+
+static struct {
+	unsigned char ctrl;
+	unsigned char timer_l;
+	unsigned char timer_h;
+	unsigned char size;
+	unsigned char ifg;
+} AQC111_BULKIN_SIZE[] = {
+	/* xHCI & EHCI & OHCI */
+	{7, 0x00, 0x01, 0x1E, 0xFF},/* 10G, 5G, 2.5G, 1G */
+	{7, 0xA0, 0x00, 0x14, 0x00},/* 100M */
+	/* Jumbo packet */
+	{7, 0x00, 0x01, 0x18, 0xFF},
+};
+
 #endif /* __LINUX_USBNET_AQC111_H */
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 net-next 07/21] net: usb: aqc111: Add support for getting and setting of MAC address
From: Igor Russkikh @ 2018-11-13 14:44 UTC (permalink / raw)
  To: David S . Miller
  Cc: linux-usb@vger.kernel.org, netdev@vger.kernel.org,
	Dmitry Bezrukov, Igor Russkikh
In-Reply-To: <cover.1542119058.git.igor.russkikh@aquantia.com>

From: Dmitry Bezrukov <dmitry.bezrukov@aquantia.com>

Signed-off-by: Dmitry Bezrukov <dmitry.bezrukov@aquantia.com>
Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com>
---
 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 <linux/netdevice.h>
 #include <linux/mii.h>
 #include <linux/usb.h>
+#include <linux/if_vlan.h>
 #include <linux/usb/cdc.h>
 #include <linux/usb/usbnet.h>
 
@@ -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, &reg8);
 
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_PARAMETERS		0x20
 #define AQ_PHY_POWER			0x31
 #define AQ_PHY_CMD			0x32
 #define AQ_PHY_OPS			0x61
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 net-next 08/21] net: usb: aqc111: Implement TX data path
From: Igor Russkikh @ 2018-11-13 14:44 UTC (permalink / raw)
  To: David S . Miller
  Cc: linux-usb@vger.kernel.org, netdev@vger.kernel.org,
	Dmitry Bezrukov, Igor Russkikh
In-Reply-To: <cover.1542119058.git.igor.russkikh@aquantia.com>

From: Dmitry Bezrukov <dmitry.bezrukov@aquantia.com>

Signed-off-by: Dmitry Bezrukov <dmitry.bezrukov@aquantia.com>
Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com>
---
 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		10000
 #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_1G		0x0011
 #define AQ_INT_SPEED_100M	0x0013
 
+/* TX Descriptor */
+#define AQ_TX_DESC_LEN_MASK	0x1FFFFF
+#define AQ_TX_DESC_DROP_PADD	BIT(28)
+
 static struct {
 	unsigned char ctrl;
 	unsigned char timer_l;
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 net-next 19/21] net: usb: aqc111: Add support for wake on LAN by MAGIC packet
From: Igor Russkikh @ 2018-11-13 14:45 UTC (permalink / raw)
  To: David S . Miller
  Cc: linux-usb@vger.kernel.org, netdev@vger.kernel.org,
	Dmitry Bezrukov, Igor Russkikh
In-Reply-To: <cover.1542119058.git.igor.russkikh@aquantia.com>

From: Dmitry Bezrukov <dmitry.bezrukov@aquantia.com>

Signed-off-by: Dmitry Bezrukov <dmitry.bezrukov@aquantia.com>
Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com>
---
 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, &reg16);
+	temp_rx_ctrl = reg16;
+	/* Stop RX operations*/
+	reg16 &= ~SFR_RX_CTL_START;
+	aqc111_write16_cmd_nopm(dev, AQ_ACCESS_MAC, SFR_RX_CTL, 2, &reg16);
+	/* Force bz */
+	aqc111_read16_cmd_nopm(dev, AQ_ACCESS_MAC, SFR_PHYPWR_RSTCTL,
+			       2, &reg16);
+	reg16 |= SFR_PHYPWR_RSTCTL_BZ;
+	aqc111_write16_cmd_nopm(dev, AQ_ACCESS_MAC, SFR_PHYPWR_RSTCTL,
+				2, &reg16);
+
+	reg8 = SFR_BULK_OUT_EFF_EN;
+	aqc111_write_cmd_nopm(dev, AQ_ACCESS_MAC, SFR_BULK_OUT_CTRL,
+			      1, 1, &reg8);
+
+	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, &reg8);
+
+	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, &reg8);
+		} 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, &reg8);
+		reg8 = SFR_BMRX_DMA_EN;
+		aqc111_write_cmd_nopm(dev, AQ_ACCESS_MAC, SFR_BMRX_DMA_CONTROL,
+				      1, 1, &reg8);
+		reg8 = SFR_RX_PATH_READY;
+		aqc111_write_cmd_nopm(dev, AQ_ACCESS_MAC, SFR_ETH_MAC_PATH,
+				      1, 1, &reg8);
+		reg8 = 0x07;
+		aqc111_write_cmd_nopm(dev, AQ_ACCESS_MAC, SFR_RX_BULKIN_QCTRL,
+				      1, 1, &reg8);
+		reg8 = 0x00;
+		aqc111_write_cmd_nopm(dev, AQ_ACCESS_MAC,
+				      SFR_RX_BULKIN_QTIMR_LOW, 1, 1, &reg8);
+		aqc111_write_cmd_nopm(dev, AQ_ACCESS_MAC,
+				      SFR_RX_BULKIN_QTIMR_HIGH, 1, 1, &reg8);
+		reg8 = 0xFF;
+		aqc111_write_cmd_nopm(dev, AQ_ACCESS_MAC, SFR_RX_BULKIN_QSIZE,
+				      1, 1, &reg8);
+		aqc111_write_cmd_nopm(dev, AQ_ACCESS_MAC, SFR_RX_BULKIN_QIFG,
+				      1, 1, &reg8);
+
+		aqc111_read16_cmd_nopm(dev, AQ_ACCESS_MAC,
+				       SFR_MEDIUM_STATUS_MODE, 2, &reg16);
+		reg16 |= SFR_MEDIUM_RECEIVE_EN;
+		aqc111_write16_cmd_nopm(dev, AQ_ACCESS_MAC,
+					SFR_MEDIUM_STATUS_MODE, 2, &reg16);
+
+		if (aqc111_data->dpa) {
+			aqc111_set_phy_speed(dev, AUTONEG_ENABLE, SPEED_100);
+		} else {
+			aqc111_write_cmd(dev, AQ_WOL_CFG, 0, 0,
+					 WOL_CFG_SIZE, &wol_cfg);
+			aqc111_write32_cmd(dev, AQ_PHY_OPS, 0, 0,
+					   &aqc111_data->phy_cfg);
+		}
+	} else {
+		aqc111_data->phy_cfg |= AQ_LOW_POWER;
+		if (!aqc111_data->dpa) {
+			aqc111_write32_cmd(dev, AQ_PHY_OPS, 0, 0,
+					   &aqc111_data->phy_cfg);
+		} else {
+			reg16 = AQ_PHY_LOW_POWER_MODE;
+			aqc111_mdio_write(dev, AQ_GLB_STD_CTRL_REG,
+					  AQ_PHY_GLOBAL_ADDR, &reg16);
+		}
+
+		/* Disable RX path */
+		aqc111_read16_cmd_nopm(dev, AQ_ACCESS_MAC,
+				       SFR_MEDIUM_STATUS_MODE, 2, &reg16);
+		reg16 &= ~SFR_MEDIUM_RECEIVE_EN;
+		aqc111_write16_cmd_nopm(dev, AQ_ACCESS_MAC,
+					SFR_MEDIUM_STATUS_MODE, 2, &reg16);
+	}
+
+	return 0;
+}
+
+static int aqc111_resume(struct usb_interface *intf)
+{
+	struct usbnet *dev = usb_get_intfdata(intf);
+	struct aqc111_data *aqc111_data = dev->driver_priv;
+	u16 reg16;
+	u8 reg8;
+
+	netif_carrier_off(dev->net);
+
+	/* Power up ethernet PHY */
+	aqc111_data->phy_cfg |= AQ_PHY_POWER_EN;
+	aqc111_data->phy_cfg &= ~AQ_LOW_POWER;
+	aqc111_data->phy_cfg &= ~AQ_WOL;
+	if (aqc111_data->dpa) {
+		aqc111_read_cmd_nopm(dev, AQ_PHY_POWER, 0, 0, 1, &reg8);
+		if (reg8 == 0x00) {
+			reg8 = 0x02;
+			aqc111_write_cmd_nopm(dev, AQ_PHY_POWER, 0, 0,
+					      1, &reg8);
+			msleep(200);
+		}
+
+		aqc111_mdio_read(dev, AQ_GLB_STD_CTRL_REG, AQ_PHY_GLOBAL_ADDR,
+				 &reg16);
+		if (reg16 & AQ_PHY_LOW_POWER_MODE) {
+			reg16 &= ~AQ_PHY_LOW_POWER_MODE;
+			aqc111_mdio_write(dev, AQ_GLB_STD_CTRL_REG,
+					  AQ_PHY_GLOBAL_ADDR, &reg16);
+		}
+	}
+
+	reg8 = 0xFF;
+	aqc111_write_cmd_nopm(dev, AQ_ACCESS_MAC, SFR_BM_INT_MASK,
+			      1, 1, &reg8);
+	/* Configure RX control register => start operation */
+	reg16 = aqc111_data->rxctl;
+	reg16 &= ~SFR_RX_CTL_START;
+	aqc111_write16_cmd_nopm(dev, AQ_ACCESS_MAC, SFR_RX_CTL, 2, &reg16);
+
+	reg16 |= SFR_RX_CTL_START;
+	aqc111_write16_cmd_nopm(dev, AQ_ACCESS_MAC, SFR_RX_CTL, 2, &reg16);
+
+	aqc111_set_phy_speed(dev, aqc111_data->autoneg,
+			     aqc111_data->advertised_speed);
+
+	aqc111_read16_cmd_nopm(dev, AQ_ACCESS_MAC, SFR_MEDIUM_STATUS_MODE,
+			       2, &reg16);
+	reg16 |= SFR_MEDIUM_RECEIVE_EN;
+	aqc111_write16_cmd_nopm(dev, AQ_ACCESS_MAC, SFR_MEDIUM_STATUS_MODE,
+				2, &reg16);
+	reg8 = SFR_RX_PATH_READY;
+	aqc111_write_cmd_nopm(dev, AQ_ACCESS_MAC, SFR_ETH_MAC_PATH,
+			      1, 1, &reg8);
+	reg8 = 0x0;
+	aqc111_write_cmd(dev, AQ_ACCESS_MAC, SFR_BMRX_DMA_CONTROL, 1, 1, &reg8);
+
+	return usbnet_resume(intf);
+}
+
 #define AQC111_USB_ETH_DEV(vid, pid, table) \
 	USB_DEVICE_INTERFACE_CLASS((vid), (pid), USB_CLASS_VENDOR_SPEC), \
 	.driver_info = (unsigned long)&(table)
@@ -1341,6 +1554,8 @@ static struct usb_driver aq_driver = {
 	.name		= "aqc111",
 	.id_table	= products,
 	.probe		= usbnet_probe,
+	.suspend	= aqc111_suspend,
+	.resume		= aqc111_resume,
 	.disconnect	= usbnet_disconnect,
 };
 
diff --git a/drivers/net/usb/aqc111.h b/drivers/net/usb/aqc111.h
index 6c951ca5d261..b62ef420bb68 100644
--- a/drivers/net/usb/aqc111.h
+++ b/drivers/net/usb/aqc111.h
@@ -19,6 +19,7 @@
 #define AQ_FLASH_PARAMETERS		0x20
 #define AQ_PHY_POWER			0x31
 #define AQ_PHY_CMD			0x32
+#define AQ_WOL_CFG			0x60
 #define AQ_PHY_OPS			0x61
 
 #define AQC111_PHY_ID			0x00
@@ -187,8 +188,18 @@
 #define AQ_DSH_RETRIES_SHIFT	0x18
 #define AQ_DSH_RETRIES_MASK	0xF000000
 
+#define AQ_WOL_FLAG_MP			0x2
+
 /******************************************************************************/
 
+struct aqc111_wol_cfg {
+	u8 hw_addr[6];
+	u8 flags;
+	u8 rsvd[283];
+} __packed;
+
+#define WOL_CFG_SIZE sizeof(struct aqc111_wol_cfg)
+
 struct aqc111_data {
 	u16 rxctl;
 	u8 rx_checksum;
@@ -203,6 +214,7 @@ struct aqc111_data {
 	} fw_ver;
 	u8 dpa; /*direct PHY access*/
 	u32 phy_cfg;
+	u8 wol_flags;
 };
 
 #define AQ_LS_MASK		0x8000
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 net-next 06/21] net: usb: aqc111: Introduce link management
From: Igor Russkikh @ 2018-11-13 14:44 UTC (permalink / raw)
  To: David S . Miller
  Cc: linux-usb@vger.kernel.org, netdev@vger.kernel.org,
	Dmitry Bezrukov, Igor Russkikh
In-Reply-To: <cover.1542119058.git.igor.russkikh@aquantia.com>

From: Dmitry Bezrukov <dmitry.bezrukov@aquantia.com>

Add full hardware initialization sequence and link configuration logic

Signed-off-by: Dmitry Bezrukov <dmitry.bezrukov@aquantia.com>
Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com>
---
 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,
+			  &reg16_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, &reg16_1);
+	aqc111_mdio_write(dev, AQ_AUTONEG_10GT_CTRL_REG,
+			  AQ_PHY_AUTONEG_ADDR, &reg16_2);
+
+	aqc111_mdio_read(dev, AQ_AUTONEG_ADV_REG, AQ_PHY_AUTONEG_ADDR,
+			 &reg16_1);
+	reg16_1 &= ~AQ_ANEG_ABILITY_MASK;
+	reg16_1 |= reg16_3;
+	aqc111_mdio_write(dev, AQ_AUTONEG_ADV_REG, AQ_PHY_AUTONEG_ADDR,
+			  &reg16_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, &reg16_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		= usbnet_open,
 	.ndo_stop		= usbnet_stop,
@@ -192,6 +308,7 @@ static void aqc111_read_fw_version(struct usbnet *dev,
 static int aqc111_bind(struct usbnet *dev, struct usb_interface *intf)
 {
 	struct usb_device *udev = interface_to_usbdev(intf);
+	enum usb_device_speed usb_speed = udev->speed;
 	struct aqc111_data *aqc111_data;
 	int ret;
 
@@ -219,6 +336,9 @@ static int aqc111_bind(struct usbnet *dev, struct usb_interface *intf)
 	dev->net->netdev_ops = &aqc111_netdev_ops;
 
 	aqc111_read_fw_version(dev, aqc111_data);
+	aqc111_data->autoneg = AUTONEG_ENABLE;
+	aqc111_data->advertised_speed = (usb_speed == USB_SPEED_SUPER) ?
+					 SPEED_5000 : SPEED_1000;
 
 	return 0;
 }
@@ -243,6 +363,7 @@ static void aqc111_unbind(struct usbnet *dev, struct usb_interface *intf)
 		aqc111_write_cmd_nopm(dev, AQ_PHY_POWER, 0,
 				      0, 1, &reg8);
 	} else {
+		aqc111_data->phy_cfg &= ~AQ_ADV_MASK;
 		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,
@@ -252,6 +373,187 @@ static void aqc111_unbind(struct usbnet *dev, struct usb_interface *intf)
 	kfree(aqc111_data);
 }
 
+static void aqc111_status(struct usbnet *dev, struct urb *urb)
+{
+	struct aqc111_data *aqc111_data = dev->driver_priv;
+	u64 *event_data = NULL;
+	int link = 0;
+
+	if (urb->actual_length < sizeof(*event_data))
+		return;
+
+	event_data = urb->transfer_buffer;
+	le64_to_cpus(event_data);
+
+	if (*event_data & AQ_LS_MASK)
+		link = 1;
+	else
+		link = 0;
+
+	aqc111_data->link_speed = (*event_data & AQ_SPEED_MASK) >>
+				  AQ_SPEED_SHIFT;
+	aqc111_data->link = link;
+
+	if (netif_carrier_ok(dev->net) != link)
+		usbnet_defer_kevent(dev, EVENT_LINK_RESET);
+}
+
+static void aqc111_configure_rx(struct usbnet *dev,
+				struct aqc111_data *aqc111_data)
+{
+	enum usb_device_speed usb_speed = dev->udev->speed;
+	u16 link_speed = 0, usb_host = 0;
+	u8 buf[5] = { 0 };
+	u8 queue_num = 0;
+	u16 reg16 = 0;
+	u8 reg8 = 0;
+
+	buf[0] = 0x00;
+	buf[1] = 0xF8;
+	buf[2] = 0x07;
+	switch (aqc111_data->link_speed) {
+	case AQ_INT_SPEED_5G:
+		link_speed = 5000;
+		reg8 = 0x05;
+		reg16 = 0x001F;
+		break;
+	case AQ_INT_SPEED_2_5G:
+		link_speed = 2500;
+		reg16 = 0x003F;
+		break;
+	case AQ_INT_SPEED_1G:
+		link_speed = 1000;
+		reg16 = 0x009F;
+		break;
+	case AQ_INT_SPEED_100M:
+		link_speed = 100;
+		queue_num = 1;
+		reg16 = 0x063F;
+		buf[1] = 0xFB;
+		buf[2] = 0x4;
+		break;
+	}
+
+	if (aqc111_data->dpa) {
+		/* Set Phy Flow control */
+		aqc111_mdio_write(dev, AQ_GLB_ING_PAUSE_CTRL_REG,
+				  AQ_PHY_AUTONEG_ADDR, &reg16);
+		aqc111_mdio_write(dev, AQ_GLB_EGR_PAUSE_CTRL_REG,
+				  AQ_PHY_AUTONEG_ADDR, &reg16);
+	}
+
+	aqc111_write_cmd(dev, AQ_ACCESS_MAC, SFR_INTER_PACKET_GAP_0,
+			 1, 1, &reg8);
+
+	aqc111_write_cmd(dev, AQ_ACCESS_MAC, SFR_TX_PAUSE_RESEND_T, 3, 3, buf);
+
+	switch (usb_speed) {
+	case USB_SPEED_SUPER:
+		usb_host = 3;
+		break;
+	case USB_SPEED_HIGH:
+		usb_host = 2;
+		break;
+	case USB_SPEED_FULL:
+	case USB_SPEED_LOW:
+		usb_host = 1;
+		queue_num = 0;
+		break;
+	default:
+		usb_host = 0;
+		break;
+	}
+
+	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;
+
+	aqc111_write16_cmd(dev, AQ_ACCESS_MAC, SFR_PAUSE_WATERLVL_LOW,
+			   2, &reg16);
+	netdev_info(dev->net, "Link Speed %d, USB %d", link_speed, usb_host);
+}
+
+static int aqc111_link_reset(struct usbnet *dev)
+{
+	struct aqc111_data *aqc111_data = dev->driver_priv;
+	u16 reg16 = 0;
+	u8 reg8 = 0;
+
+	if (aqc111_data->link == 1) { /* Link up */
+		aqc111_configure_rx(dev, aqc111_data);
+
+		/* Vlan Tag Filter */
+		reg8 = SFR_VLAN_CONTROL_VSO;
+
+		aqc111_write_cmd(dev, AQ_ACCESS_MAC, SFR_VLAN_ID_CONTROL,
+				 1, 1, &reg8);
+
+		reg8 = 0x0;
+		aqc111_write_cmd(dev, AQ_ACCESS_MAC, SFR_BMRX_DMA_CONTROL,
+				 1, 1, &reg8);
+
+		aqc111_write_cmd(dev, AQ_ACCESS_MAC, SFR_BMTX_DMA_CONTROL,
+				 1, 1, &reg8);
+
+		aqc111_write_cmd(dev, AQ_ACCESS_MAC, SFR_ARC_CTRL, 1, 1, &reg8);
+
+		reg16 = SFR_RX_CTL_IPE | SFR_RX_CTL_AB;
+		aqc111_write16_cmd(dev, AQ_ACCESS_MAC, SFR_RX_CTL, 2, &reg16);
+
+		reg8 = SFR_RX_PATH_READY;
+		aqc111_write_cmd(dev, AQ_ACCESS_MAC, SFR_ETH_MAC_PATH,
+				 1, 1, &reg8);
+
+		reg8 = SFR_BULK_OUT_EFF_EN;
+		aqc111_write_cmd(dev, AQ_ACCESS_MAC, SFR_BULK_OUT_CTRL,
+				 1, 1, &reg8);
+
+		reg16 = 0;
+		aqc111_write16_cmd(dev, AQ_ACCESS_MAC, SFR_MEDIUM_STATUS_MODE,
+				   2, &reg16);
+
+		reg16 = SFR_MEDIUM_XGMIIMODE | SFR_MEDIUM_FULL_DUPLEX;
+		aqc111_write16_cmd(dev, AQ_ACCESS_MAC, SFR_MEDIUM_STATUS_MODE,
+				   2, &reg16);
+
+		aqc111_read16_cmd(dev, AQ_ACCESS_MAC, SFR_MEDIUM_STATUS_MODE,
+				  2, &reg16);
+
+		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, &reg16);
+
+		reg16 = SFR_RX_CTL_IPE | SFR_RX_CTL_AB | SFR_RX_CTL_START;
+		aqc111_write16_cmd(dev, AQ_ACCESS_MAC, SFR_RX_CTL, 2, &reg16);
+
+		netif_carrier_on(dev->net);
+	} else {
+		aqc111_read16_cmd(dev, AQ_ACCESS_MAC, SFR_MEDIUM_STATUS_MODE,
+				  2, &reg16);
+		reg16 &= ~SFR_MEDIUM_RECEIVE_EN;
+		aqc111_write16_cmd(dev, AQ_ACCESS_MAC, SFR_MEDIUM_STATUS_MODE,
+				   2, &reg16);
+
+		aqc111_read16_cmd(dev, AQ_ACCESS_MAC, SFR_RX_CTL, 2, &reg16);
+		reg16 &= ~SFR_RX_CTL_START;
+		aqc111_write16_cmd(dev, AQ_ACCESS_MAC, SFR_RX_CTL, 2, &reg16);
+
+		reg8 = SFR_BULK_OUT_FLUSH_EN | SFR_BULK_OUT_EFF_EN;
+		aqc111_write_cmd(dev, AQ_ACCESS_MAC, SFR_BULK_OUT_CTRL,
+				 1, 1, &reg8);
+		reg8 = SFR_BULK_OUT_EFF_EN;
+		aqc111_write_cmd(dev, AQ_ACCESS_MAC, SFR_BULK_OUT_CTRL,
+				 1, 1, &reg8);
+
+		netif_carrier_off(dev->net);
+	}
+	return 0;
+}
+
 static int aqc111_reset(struct usbnet *dev)
 {
 	struct aqc111_data *aqc111_data = dev->driver_priv;
@@ -292,6 +594,12 @@ static int aqc111_reset(struct usbnet *dev)
 		  SFR_MONITOR_MODE_RW_FLAG);
 	aqc111_write_cmd(dev, AQ_ACCESS_MAC, SFR_MONITOR_MODE, 1, 1, &reg8);
 
+	netif_carrier_off(dev->net);
+
+	/* Phy advertise */
+	aqc111_set_phy_speed(dev, aqc111_data->autoneg,
+			     aqc111_data->advertised_speed);
+
 	return 0;
 }
 
@@ -319,6 +627,8 @@ static int aqc111_stop(struct usbnet *dev)
 				   &aqc111_data->phy_cfg);
 	}
 
+	netif_carrier_off(dev->net);
+
 	return 0;
 }
 
@@ -326,6 +636,8 @@ static const struct driver_info aqc111_info = {
 	.description	= "Aquantia AQtion USB to 5GbE Controller",
 	.bind		= aqc111_bind,
 	.unbind		= aqc111_unbind,
+	.status		= aqc111_status,
+	.link_reset	= aqc111_link_reset,
 	.reset		= aqc111_reset,
 	.stop		= aqc111_stop,
 };
diff --git a/drivers/net/usb/aqc111.h b/drivers/net/usb/aqc111.h
index ac0bbeabf563..fd49a43e6d93 100644
--- a/drivers/net/usb/aqc111.h
+++ b/drivers/net/usb/aqc111.h
@@ -18,12 +18,44 @@
 #define AQC111_PHY_ID			0x00
 #define AQ_PHY_ADDR(mmd)		((AQC111_PHY_ID << 8) | mmd)
 
+#define AQ_PHY_AUTONEG_MMD		0x07
+#define AQ_PHY_AUTONEG_ADDR		AQ_PHY_ADDR(AQ_PHY_AUTONEG_MMD)
+
+#define AQ_AUTONEG_STD_CTRL_REG		0x0000
+	#define AQ_ANEG_EX_PAGE_CTRL		0x2000
+	#define AQ_ANEG_EN_ANEG			0x1000
+	#define AQ_ANEG_RESTART_ANEG		0x0200
+
+#define AQ_AUTONEG_ADV_REG		0x0010
+	#define AQ_ANEG_100M			0x0100
+	#define AQ_ANEG_PAUSE			0x0400
+	#define AQ_ANEG_ASYM_PAUSE		0x0800
+	#define AQ_ANEG_ABILITY_MASK		0x0FE0
+
+#define AQ_AUTONEG_10GT_CTRL_REG	0x0020
+	#define AQ_ANEG_ADV_10G_T		0x1000
+	#define AQ_ANEG_ADV_5G_T		0x0100
+	#define AQ_ANEG_ADV_2G5_T		0x0080
+	#define AQ_ANEG_ADV_LT			0x0001
+
+#define AQ_AUTONEG_VEN_PROV1_REG	0xC400
+	#define AQ_ANEG_ADV_1G			0x8000
+	#define AQ_ANEG_ADV_AQRATE		0x1000
+	#define AQ_ANEG_ADV_5G_N		0x0800
+	#define AQ_ANEG_ADV_2G5_N		0x0400
+	#define AQ_ANEG_EX_PHY_ID		0x0040
+	#define AQ_ANEG_EN_DSH			0x0010
+	#define AQ_ANEG_DSH_RETRY		0x0003
+
 #define AQ_PHY_GLOBAL_MMD		0x1E
 #define AQ_PHY_GLOBAL_ADDR		AQ_PHY_ADDR(AQ_PHY_GLOBAL_MMD)
 
 #define AQ_GLB_STD_CTRL_REG		0x0000
 	#define AQ_PHY_LOW_POWER_MODE		0x0800
 
+#define AQ_GLB_ING_PAUSE_CTRL_REG	0x7148
+#define AQ_GLB_EGR_PAUSE_CTRL_REG	0x4148
+
 #define AQ_USB_PHY_SET_TIMEOUT		10000
 #define AQ_USB_SET_TIMEOUT		4000
 
@@ -123,6 +155,7 @@
 #define AQ_ADV_1G	BIT(1)
 #define AQ_ADV_2G5	BIT(2)
 #define AQ_ADV_5G	BIT(3)
+#define AQ_ADV_MASK	0x0F
 
 #define AQ_PAUSE	BIT(16)
 #define AQ_ASYM_PAUSE	BIT(17)
@@ -137,6 +170,10 @@
 /******************************************************************************/
 
 struct aqc111_data {
+	u8 link_speed;
+	u8 link;
+	u8 autoneg;
+	u32 advertised_speed;
 	struct {
 		u8 major;
 		u8 minor;
@@ -146,6 +183,14 @@ struct aqc111_data {
 	u32 phy_cfg;
 };
 
+#define AQ_LS_MASK		0x8000
+#define AQ_SPEED_MASK		0x7F00
+#define AQ_SPEED_SHIFT		0x0008
+#define AQ_INT_SPEED_5G		0x000F
+#define AQ_INT_SPEED_2_5G	0x0010
+#define AQ_INT_SPEED_1G		0x0011
+#define AQ_INT_SPEED_100M	0x0013
+
 static struct {
 	unsigned char ctrl;
 	unsigned char timer_l;
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 net-next 20/21] net: usb: aqc111: Add ASIX's HW ids
From: Igor Russkikh @ 2018-11-13 14:45 UTC (permalink / raw)
  To: David S . Miller
  Cc: linux-usb@vger.kernel.org, netdev@vger.kernel.org,
	Dmitry Bezrukov, Igor Russkikh
In-Reply-To: <cover.1542119058.git.igor.russkikh@aquantia.com>

From: Dmitry Bezrukov <dmitry.bezrukov@aquantia.com>

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

Signed-off-by: Dmitry Bezrukov <dmitry.bezrukov@aquantia.com>
Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com>
---
 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

^ permalink raw reply related

* [PATCH v2 net-next 21/21] net: usb: aqc111: Extend cdc_ether blacklist
From: Igor Russkikh @ 2018-11-13 14:45 UTC (permalink / raw)
  To: David S . Miller
  Cc: linux-usb@vger.kernel.org, netdev@vger.kernel.org,
	Dmitry Bezrukov, Igor Russkikh
In-Reply-To: <cover.1542119058.git.igor.russkikh@aquantia.com>

From: Dmitry Bezrukov <dmitry.bezrukov@aquantia.com>

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 <dmitry.bezrukov@aquantia.com>
Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com>
---
 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_ID	0x045e
 #define UBLOX_VENDOR_ID		0x1546
 #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

^ permalink raw reply related

* Re: [PATCH net] l2tp: fix a sock refcnt leak in l2tp_tunnel_register
From: Guillaume Nault @ 2018-11-13 14:51 UTC (permalink / raw)
  To: Xin Long; +Cc: network dev, davem
In-Reply-To: <7e6ee3c12afb3c98bd1b49e5825803ab1efed4c1.1542042505.git.lucien.xin@gmail.com>

On Tue, Nov 13, 2018 at 01:08:25AM +0800, Xin Long wrote:
> This issue happens when trying to add an existent tunnel. It
> doesn't call sock_put() before returning -EEXIST to release
> the sock refcnt that was held by calling sock_hold() before
> the existence check.
> 
> This patch is to fix it by holding the sock after doing the
> existence check.
> 
Nice fix. Thanks Xin!

Reviewed-by: Guillaume Nault <g.nault@alphalink.fr>

^ permalink raw reply

* [iproute PATCH] ip-address: Fix filtering by negated address flags
From: Phil Sutter @ 2018-11-13 15:12 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev

When disabling a flag, one needs to AND with the inverse not the flag
itself. Otherwise specifying for instance 'home -nodad' will effectively
clear the flags variable.

While being at it, simplify the code a bit by merging common parts of
negated and non-negated case branches. Also allow for the "special
cases" to be inverted, too.

Fixes: f73ac674d0abf ("ip: change flag names to an array")
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
 ip/ipaddress.c | 32 ++++++++++++++++++--------------
 1 file changed, 18 insertions(+), 14 deletions(-)

diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index cd8cc76a3473f..7b98877085878 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -1211,31 +1211,35 @@ static void print_ifa_flags(FILE *fp, const struct ifaddrmsg *ifa,
 
 static int get_filter(const char *arg)
 {
+	bool inv = false;
 	unsigned int i;
 
+	if (arg[0] == '-') {
+		inv = true;
+		arg++;
+	}
 	/* Special cases */
 	if (strcmp(arg, "dynamic") == 0) {
-		filter.flags &= ~IFA_F_PERMANENT;
+		if (inv)
+			filter.flags |= IFA_F_PERMANENT;
+		else
+			filter.flags &= ~IFA_F_PERMANENT;
 		filter.flagmask |= IFA_F_PERMANENT;
 	} else if (strcmp(arg, "primary") == 0) {
-		filter.flags &= ~IFA_F_SECONDARY;
+		if (inv)
+			filter.flags |= IFA_F_SECONDARY;
+		else
+			filter.flags &= ~IFA_F_SECONDARY;
 		filter.flagmask |= IFA_F_SECONDARY;
-	} else if (*arg == '-') {
-		for (i = 0; i < ARRAY_SIZE(ifa_flag_names); i++) {
-			if (strcmp(arg + 1, ifa_flag_names[i].name))
-				continue;
-
-			filter.flags &= ifa_flag_names[i].value;
-			filter.flagmask |= ifa_flag_names[i].value;
-			return 0;
-		}
-
-		return -1;
 	} else {
 		for (i = 0; i < ARRAY_SIZE(ifa_flag_names); i++) {
 			if (strcmp(arg, ifa_flag_names[i].name))
 				continue;
-			filter.flags |= ifa_flag_names[i].value;
+
+			if (inv)
+				filter.flags &= ~ifa_flag_names[i].value;
+			else
+				filter.flags |= ifa_flag_names[i].value;
 			filter.flagmask |= ifa_flag_names[i].value;
 			return 0;
 		}
-- 
2.19.0

^ permalink raw reply related

* Re: [PATCH bpf-next v2] bpftool: make libbfd optional
From: Stanislav Fomichev @ 2018-11-13 15:45 UTC (permalink / raw)
  To: Quentin Monnet
  Cc: Jakub Kicinski, Stanislav Fomichev, netdev, ast, daniel,
	Jiong Wang
In-Reply-To: <c34fe18a-5f23-7b7d-7062-54bf9f7ad125@netronome.com>

On 11/13, Quentin Monnet wrote:
> 2018-11-12 14:02 UTC-0800 ~ Jakub Kicinski <jakub.kicinski@netronome.com>
> > On Mon, 12 Nov 2018 13:44:10 -0800, Stanislav Fomichev wrote:
> >> Make it possible to build bpftool without libbfd. libbfd and libopcodes are
> >> typically provided in dev/dbg packages (binutils-dev in debian) which we
> >> usually don't have installed on the fleet machines and we'd like a way to have
> >> bpftool version that works without installing any additional packages.
> >> This excludes support for disassembling jit-ted code and prints an error if
> >> the user tries to use these features.
> >>
> >> Tested by:
> >> cat > FEATURES_DUMP.bpftool <<EOF
> >> feature-libbfd=0
> >> feature-disassembler-four-args=1
> >> feature-reallocarray=0
> >> feature-libelf=1
> >> feature-libelf-mmap=1
> >> feature-bpf=1
> >> EOF
> >> FEATURES_DUMP=$PWD/FEATURES_DUMP.bpftool make
> >> ldd bpftool | grep libbfd
> >>
> >> Signed-off-by: Stanislav Fomichev <sdf@google.com>
> > 
> > Seems reasonable, thanks!
> > 
> > Acked-by: Jakub Kicinski <jakub.kicinski@netronome.com>
> > 
> 
> Thanks Stanislav!
> 
> There is a problem with this patch on some distributions, Ubuntu at least.
> 
> Feature detection for libbfd has been used for perf before being also
> used with bpftool. Since commit 280e7c48c3b8 the feature needs libz and
> libiberty to be present on the system, otherwise the feature would not
> compile (and be detected) on OpenSuse.
> 
> On Ubuntu, libiberty is not needed (libbfd might be statically linked
> against it, if I remember correctly?), which means that we are able to
> build bpftool as long as binutils-dev has been installed, even if
> libiberty-dev has not been installed. The BFD feature, in that case,
> will appear as “undetected”. It is a bug. But since the Makefile does
> not stop compilation in that case (another bug), in the end we're good.
> 
> With your patch, the problem is that libbpf detection will fail on
> Ubuntu if libiberty-dev is not present, even though all the necessary
> libraries for using the JIT disassembler are available. And in that case
> it _will_ make a difference, since the Makefile will no more compile the
> libbfd-related bits.
> 
> So I'm not against the idea, but we have to fix libbfd detection first.
Yeah, libbfd feature detection looks broken on ubuntu, this patch just
exercises this brokenness :-). I can take a look somewhere this week,
thanks for spotting it!

I wonder, how does it work on opensuse currently if we link only against -lbfd
(https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tools/bpf/bpftool/Makefile#n56)?
It might be broken everywhere...

(Resent with proper formatting and without HTML).
> Thanks,
> Quentin

^ permalink raw reply

* Re: [PATCH net-next 16/17] net: sched: conditionally take rtnl lock on rules update path
From: Stefano Brivio @ 2018-11-13 15:53 UTC (permalink / raw)
  To: Vlad Buslov
  Cc: netdev@vger.kernel.org, jhs@mojatatu.com,
	xiyou.wangcong@gmail.com, jiri@resnulli.us, davem@davemloft.net,
	ast@kernel.org, daniel@iogearbox.net
In-Reply-To: <vbfefbpjd3r.fsf@reg-r-vrt-018-180.mtr.labs.mlnx>

On Tue, 13 Nov 2018 13:58:05 +0000
Vlad Buslov <vladbu@mellanox.com> wrote:

> On Tue 13 Nov 2018 at 13:40, Stefano Brivio <sbrivio@redhat.com> wrote:
> > On Tue, 13 Nov 2018 13:25:52 +0000
> > Vlad Buslov <vladbu@mellanox.com> wrote:
> >  
> >> On Tue 13 Nov 2018 at 09:40, Stefano Brivio <sbrivio@redhat.com> wrote:  
> >> > Hi Vlad,
> >> >
> >> > On Mon, 12 Nov 2018 09:55:45 +0200
> >> > Vlad Buslov <vladbu@mellanox.com> wrote:
> >> >    
> >> >> @@ -179,9 +179,25 @@ static void tcf_proto_destroy_work(struct work_struct *work)
> >> >>  	rtnl_unlock();
> >> >>  }
> >> >>  
> >> >> +/* Helper function to lock rtnl mutex when specified condition is true and mutex
> >> >> + * hasn't been locked yet. Will set rtnl_held to 'true' before taking rtnl lock.
> >> >> + * Note that this function does nothing if rtnl is already held. This is
> >> >> + * intended to be used by cls API rules update API when multiple conditions
> >> >> + * could require rtnl lock and its state needs to be tracked to prevent trying
> >> >> + * to obtain lock multiple times.
> >> >> + */
> >> >> +
> >> >> +static void tcf_require_rtnl(bool cond, bool *rtnl_held)
> >> >> +{
> >> >> +	if (!*rtnl_held && cond) {
> >> >> +		*rtnl_held = true;
> >> >> +		rtnl_lock();
> >> >> +	}
> >> >> +}    
> >> >
> >> > I guess calls to this function are supposed to be serialised. If that's
> >> > the case (which is my tentative understanding so far), I would indicate
> >> > that in the comment.
> >> >
> >> > If that's not the case, you would be introducing a race I guess.
> >> >
> >> > Same applies to tcf_block_release() from 17/17.    
> >> 
> >> Hi Stefano,
> >> 
> >> Thank you for reviewing my code!
> >> 
> >> I did not intend for this function to be serialized. First argument to
> >> tcf_require_rtnl() is passed by value, and second argument is always a
> >> pointer to local stack-allocated value of the caller.  
> >
> > Yes, sorry, I haven't been terribly clear, that's what I meant by
> > serialised: it won't be called concurrently with the same *rtnl_held.
> >
> > Perhaps the risk that somebody uses it that way is close to zero, so
> > I'm not even too sure this is worth a comment, but if you can come up
> > with a concise way of saying this, that would be nice.  
> 
> I considered my comment that function "Will set rtnl_held to 'true'
> before taking rtnl lock" as a red flag for caller to not pass pointer to
> a variable that can be accessed concurrently. I guess I can add
> additional sentence to explicitly warn potential users. Or I can just
> move rtnl_held assignment in both functions to be performed while
> holding rtnl mutex. I implemented it the way I did as an overzealous
> optimization, but realistically price of an assignment is negligible in
> this case.

But to make that effective, you would need to protect the read too, and
that makes your optimisation not really overzealous I think.

I'd rather go with an additional comment, if that doesn't become
unreadable.

-- 
Stefano

^ permalink raw reply

* [iproute PATCH v2] man: ip-route.8: Document nexthop limit
From: Phil Sutter @ 2018-11-13 15:55 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev, David Ahern

Add a note to 'nexthop' description stating the maximum number of
nexthops per command and pointing at 'append' command as a workaround.

Signed-off-by: Phil Sutter <phil@nwl.cc>
---
Changes since v1:
- Reviewed text.
- 'route append' trick works with IPv6 only.
---
 man/man8/ip-route.8.in | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/man/man8/ip-route.8.in b/man/man8/ip-route.8.in
index a33ce1f0f4006..11dd4ca7abf68 100644
--- a/man/man8/ip-route.8.in
+++ b/man/man8/ip-route.8.in
@@ -589,6 +589,15 @@ argument lists:
 route reflecting its relative bandwidth or quality.
 .in -8
 
+The internal buffer used in iproute2 limits the maximum number of nexthops that
+may be specified in one go. If only
+.I ADDRESS
+is given, the current buffer size allows for 144 IPv6 nexthops and 253 IPv4
+ones. For IPv4, this effectively limits the number of nexthops possible per
+route. With IPv6, further nexthops may be appended to the same route via
+.B "ip route append"
+command.
+
 .TP
 .BI scope " SCOPE_VAL"
 the scope of the destinations covered by the route prefix.
-- 
2.19.0

^ permalink raw reply related

* Re: [PATCH net-next 01/17] net: sched: refactor mini_qdisc_pair_swap() to use workqueue
From: David Miller @ 2018-11-13 16:08 UTC (permalink / raw)
  To: vladbu; +Cc: netdev, jhs, xiyou.wangcong, jiri, ast, daniel
In-Reply-To: <vbfk1lhjf2s.fsf@reg-r-vrt-018-180.mtr.labs.mlnx>

From: Vlad Buslov <vladbu@mellanox.com>
Date: Tue, 13 Nov 2018 13:13:19 +0000

> 
> On Mon 12 Nov 2018 at 17:28, David Miller <davem@davemloft.net> wrote:
>> From: Vlad Buslov <vladbu@mellanox.com>
>> Date: Mon, 12 Nov 2018 09:55:30 +0200
>>
>>> +void mini_qdisc_pair_swap(struct mini_Qdisc_pair *miniqp,
>>> +			  struct tcf_proto *tp_head)
>>> +{
>>> +	xchg(&miniqp->tp_head, tp_head);
>>
>> If you are not checking the return value of xchg(), then this is
>> simply a store with optionally a memory barrier of some sort
>> either before or after.
> 
> That was my intention. What would be a better way to atomically
> reset a pointer? Should I just change this line to explicit
> assignment+barrier?

We have all kinds of helpers in the kernel for doing things like
this, grep for things like "smp_load_acquire", "smp_store_release()"
etc.

^ permalink raw reply

* BUG: sleeping function called from invalid context at mm/slab.h:421
From: Naresh Kamboju @ 2018-11-13 16:33 UTC (permalink / raw)
  To: netdev; +Cc: Roman Gushchin, ast, Daniel Borkmann, kafai

While running kernel selftests bpf test_cgroup_storage test this
kernel BUG reported every time on all devices running Linux -next
4.20.0-rc2-next-20181113 (from 4.19.0-rc5-next-20180928).
This kernel BUG log is from x86_64 machine.

Do you see at your end ?

[   73.047526] BUG: sleeping function called from invalid context at
/srv/oe/build/tmp-rpb-glibc/work-shared/intel-corei7-64/kernel-source/mm/slab.h:421
[   73.060915] in_atomic(): 1, irqs_disabled(): 0, pid: 3157, name:
test_cgroup_sto
[   73.068342] INFO: lockdep is turned off.
[   73.072293] CPU: 2 PID: 3157 Comm: test_cgroup_sto Not tainted
4.20.0-rc2-next-20181113 #1
[   73.080548] Hardware name: Supermicro SYS-5019S-ML/X11SSH-F, BIOS
2.0b 07/27/2017
[   73.088018] Call Trace:
[   73.090463]  dump_stack+0x70/0xa5
[   73.093783]  ___might_sleep+0x152/0x240
[   73.097619]  __might_sleep+0x4a/0x80
[   73.101191]  __kmalloc_node+0x1cf/0x2f0
[   73.105031]  ? cgroup_storage_update_elem+0x46/0x90
[   73.109909]  cgroup_storage_update_elem+0x46/0x90
[   73.114608]  map_update_elem+0x4a1/0x4c0
[   73.118534]  __x64_sys_bpf+0x124/0x280
[   73.122286]  do_syscall_64+0x4f/0x190
[   73.125952]  entry_SYSCALL_64_after_hwframe+0x49/0xbe
[   73.131004] RIP: 0033:0x7f46b93ea7f9
[   73.134581] Code: 00 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00
00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24
08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 4f e6 2b 00 f7 d8 64 89
01 48
[   73.153318] RSP: 002b:00007fffc6595858 EFLAGS: 00000206 ORIG_RAX:
0000000000000141
[   73.160876] RAX: ffffffffffffffda RBX: 00000000014a0260 RCX: 00007f46b93ea7f9
[   73.167999] RDX: 0000000000000048 RSI: 00007fffc65958a0 RDI: 0000000000000002
[   73.175124] RBP: 00007fffc6595870 R08: 00007fffc65958a0 R09: 00007fffc65958a0
[   73.182246] R10: 00007fffc65958a0 R11: 0000000000000206 R12: 0000000000000003
[   73.189369] R13: 0000000000000004 R14: 0000000000000005 R15: 0000000000000006
selftests: bpf: test_cgroup_storage

Please find full test log,
https://lkft.validation.linaro.org/scheduler/job/506640#L2874

Thank you.
Best regards
Naresh Kamboju

^ permalink raw reply

* [PATCH bpf-next v2] filter: add BPF_ADJ_ROOM_DATA mode to bpf_skb_adjust_room()
From: Nicolas Dichtel @ 2018-11-13 16:35 UTC (permalink / raw)
  To: kafai; +Cc: ast, daniel, davem, netdev, Nicolas Dichtel
In-Reply-To: <20181112183939.xhiwgbqeaprvscu7@kafai-mbp.dhcp.thefacebook.com>

This new mode enables to add or remove an l2 header in a programmatic way
with cls_bpf.
For example, it enables to play with mpls headers.

Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Acked-by: Martin KaFai Lau <kafai@fb.com>
---

v2: use skb_set_network_header()

 include/uapi/linux/bpf.h       |  3 ++
 net/core/filter.c              | 53 ++++++++++++++++++++++++++++++++++
 tools/include/uapi/linux/bpf.h |  3 ++
 3 files changed, 59 insertions(+)

diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 47d606d744cc..9762ef3a536c 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -1467,6 +1467,8 @@ union bpf_attr {
  *
  * 		* **BPF_ADJ_ROOM_NET**: Adjust room at the network layer
  * 		  (room space is added or removed below the layer 3 header).
+ * 		* **BPF_ADJ_ROOM_DATA**: Adjust room at the beginning of the
+ * 		  packet (room space is added or removed below skb->data).
  *
  * 		All values for *flags* are reserved for future usage, and must
  * 		be left at zero.
@@ -2412,6 +2414,7 @@ enum bpf_func_id {
 /* Mode for BPF_FUNC_skb_adjust_room helper. */
 enum bpf_adj_room_mode {
 	BPF_ADJ_ROOM_NET,
+	BPF_ADJ_ROOM_DATA,
 };
 
 /* Mode for BPF_FUNC_skb_load_bytes_relative helper. */
diff --git a/net/core/filter.c b/net/core/filter.c
index 53d50fb75ea1..e56da3077dca 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -2884,6 +2884,57 @@ static int bpf_skb_adjust_net(struct sk_buff *skb, s32 len_diff)
 	return ret;
 }
 
+static int bpf_skb_data_shrink(struct sk_buff *skb, u32 len)
+{
+	unsigned short hhlen = skb->dev->header_ops ?
+			       skb->dev->hard_header_len : 0;
+	int ret;
+
+	ret = skb_unclone(skb, GFP_ATOMIC);
+	if (unlikely(ret < 0))
+		return ret;
+
+	__skb_pull(skb, len);
+	skb_reset_mac_header(skb);
+	skb_set_network_header(skb, hhlen);
+	skb_reset_transport_header(skb);
+	return 0;
+}
+
+static int bpf_skb_data_grow(struct sk_buff *skb, u32 len)
+{
+	unsigned short hhlen = skb->dev->header_ops ?
+			       skb->dev->hard_header_len : 0;
+	int ret;
+
+	ret = skb_cow(skb, len);
+	if (unlikely(ret < 0))
+		return ret;
+
+	skb_push(skb, len);
+	skb_reset_mac_header(skb);
+	return 0;
+}
+
+static int bpf_skb_adjust_data(struct sk_buff *skb, s32 len_diff)
+{
+	u32 len_diff_abs = abs(len_diff);
+	bool shrink = len_diff < 0;
+	int ret;
+
+	if (unlikely(len_diff_abs > 0xfffU))
+		return -EFAULT;
+
+	if (shrink && len_diff_abs >= skb_headlen(skb))
+		return -EFAULT;
+
+	ret = shrink ? bpf_skb_data_shrink(skb, len_diff_abs) :
+		       bpf_skb_data_grow(skb, len_diff_abs);
+
+	bpf_compute_data_pointers(skb);
+	return ret;
+}
+
 BPF_CALL_4(bpf_skb_adjust_room, struct sk_buff *, skb, s32, len_diff,
 	   u32, mode, u64, flags)
 {
@@ -2891,6 +2942,8 @@ BPF_CALL_4(bpf_skb_adjust_room, struct sk_buff *, skb, s32, len_diff,
 		return -EINVAL;
 	if (likely(mode == BPF_ADJ_ROOM_NET))
 		return bpf_skb_adjust_net(skb, len_diff);
+	if (likely(mode == BPF_ADJ_ROOM_DATA))
+		return bpf_skb_adjust_data(skb, len_diff);
 
 	return -ENOTSUPP;
 }
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index 852dc17ab47a..47407fd5162b 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -1467,6 +1467,8 @@ union bpf_attr {
  *
  * 		* **BPF_ADJ_ROOM_NET**: Adjust room at the network layer
  * 		  (room space is added or removed below the layer 3 header).
+ * 		* **BPF_ADJ_ROOM_DATA**: Adjust room at the beginning of the
+ * 		  packet (room space is added or removed below skb->data).
  *
  * 		All values for *flags* are reserved for future usage, and must
  * 		be left at zero.
@@ -2408,6 +2410,7 @@ enum bpf_func_id {
 /* Mode for BPF_FUNC_skb_adjust_room helper. */
 enum bpf_adj_room_mode {
 	BPF_ADJ_ROOM_NET,
+	BPF_ADJ_ROOM_DATA,
 };
 
 /* Mode for BPF_FUNC_skb_load_bytes_relative helper. */
-- 
2.18.0

^ permalink raw reply related

* [PATCH net] ipv6: fix a dst leak when removing its exception
From: Xin Long @ 2018-11-13 16:48 UTC (permalink / raw)
  To: network dev; +Cc: davem, David Ahern

These is no need to hold dst before calling rt6_remove_exception_rt().
The call to dst_hold_safe() in ip6_link_failure() was for ip6_del_rt(),
which has been removed in Commit 93531c674315 ("net/ipv6: separate
handling of FIB entries from dst based routes"). Otherwise, it will
cause a dst leak.

This patch is to simply remove the dst_hold_safe() call before calling
rt6_remove_exception_rt() and also do the same in ip6_del_cached_rt().
It's safe, because the removal of the exception that holds its dst's
refcnt is protected by rt6_exception_lock.

Fixes: 93531c674315 ("net/ipv6: separate handling of FIB entries from dst based routes")
Fixes: 23fb93a4d3f1 ("net/ipv6: Cleanup exception and cache route handling")
Reported-by: Li Shuang <shuali@redhat.com>
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
 net/ipv6/route.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 2a7423c..14b422f 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -2232,8 +2232,7 @@ static void ip6_link_failure(struct sk_buff *skb)
 	if (rt) {
 		rcu_read_lock();
 		if (rt->rt6i_flags & RTF_CACHE) {
-			if (dst_hold_safe(&rt->dst))
-				rt6_remove_exception_rt(rt);
+			rt6_remove_exception_rt(rt);
 		} else {
 			struct fib6_info *from;
 			struct fib6_node *fn;
@@ -3214,8 +3213,8 @@ static int ip6_del_cached_rt(struct rt6_info *rt, struct fib6_config *cfg)
 	if (cfg->fc_flags & RTF_GATEWAY &&
 	    !ipv6_addr_equal(&cfg->fc_gateway, &rt->rt6i_gateway))
 		goto out;
-	if (dst_hold_safe(&rt->dst))
-		rc = rt6_remove_exception_rt(rt);
+
+	rc = rt6_remove_exception_rt(rt);
 out:
 	return rc;
 }
-- 
2.1.0

^ permalink raw reply related

* Re: pull-request: can 2018-11-09
From: David Miller @ 2018-11-13 16:43 UTC (permalink / raw)
  To: mkl; +Cc: netdev, linux-can, kernel
In-Reply-To: <20181112115728.18331-1-mkl@pengutronix.de>

From: Marc Kleine-Budde <mkl@pengutronix.de>
Date: Mon, 12 Nov 2018 12:57:08 +0100

> this is a pull request of 20 patches for net/master.

Pulled, thanks Marc.

^ permalink raw reply

* Re: [PATCH net v2 0/4] qed: Miscellaneous bug fixes
From: David Miller @ 2018-11-13 16:51 UTC (permalink / raw)
  To: denis.bolotin; +Cc: netdev, michal.kalderon, ariel.elior
In-Reply-To: <20181112105023.23842-1-denis.bolotin@cavium.com>

From: Denis Bolotin <denis.bolotin@cavium.com>
Date: Mon, 12 Nov 2018 12:50:19 +0200

> This patch series fixes several unrelated bugs across the driver.
> Please consider applying to net.
> 
> V1->V2:
> -------
> Use dma_rmb() instead of rmb().

Series applied, thank you.

^ permalink raw reply

* Re: [PATCH net-next 16/17] net: sched: conditionally take rtnl lock on rules update path
From: Stefano Brivio @ 2018-11-13 16:57 UTC (permalink / raw)
  To: Vlad Buslov
  Cc: netdev@vger.kernel.org, jhs@mojatatu.com,
	xiyou.wangcong@gmail.com, jiri@resnulli.us, davem@davemloft.net,
	ast@kernel.org, daniel@iogearbox.net
In-Reply-To: <20181113165307.45987362@redhat.com>

On Tue, 13 Nov 2018 16:53:07 +0100
Stefano Brivio <sbrivio@redhat.com> wrote:

> But to make that effective, you would need to protect the read too, and
> that makes your optimisation not really overzealous I think.
> 
> I'd rather go with an additional comment, if that doesn't become
> unreadable.

Oh, and of course, this whole thing makes sense only if for some reason
you end up keeping this function. Maybe ignore my comments on this patch
at least for the moment being ;)

-- 
Stefano

^ permalink raw reply

* Re: [RFCv3 PATCH 1/6] uacce: Add documents for WarpDrive/uacce
From: Kenneth Lee @ 2018-11-14  2:58 UTC (permalink / raw)
  To: Leon Romanovsky
  Cc: Alexander Shishkin, Tim Sell, Sanyog Kale, Randy Dunlap,
	Uwe Kleine-König, Vinod Koul, David Kershner, Sagar Dharia,
	Gavin Schenk, Jens Axboe, Philippe Ombredanne, Cyrille Pitchen,
	Johan Hovold, Zhou Wang, Hao Fang, Jonathan Cameron, Zaibo Xu,
	linux-doc, linux-kernel
In-Reply-To: <20181113002354.GO3695@mtr-leonro.mtl.com>


在 2018/11/13 上午8:23, Leon Romanovsky 写道:
> On Mon, Nov 12, 2018 at 03:58:02PM +0800, Kenneth Lee wrote:
>> From: Kenneth Lee <liguozhu@hisilicon.com>
>>
>> WarpDrive is a general accelerator framework for the user application to
>> access the hardware without going through the kernel in data path.
>>
>> The kernel component to provide kernel facility to driver for expose the
>> user interface is called uacce. It a short name for
>> "Unified/User-space-access-intended Accelerator Framework".
>>
>> This patch add document to explain how it works.
> + RDMA and netdev folks
>
> Sorry, to be late in the game, I don't see other patches, but from
> the description below it seems like you are reinventing RDMA verbs
> model. I have hard time to see the differences in the proposed
> framework to already implemented in drivers/infiniband/* for the kernel
> space and for the https://github.com/linux-rdma/rdma-core/ for the user
> space parts.

Thanks Leon,

Yes, we tried to solve similar problem in RDMA. We also learned a lot 
from the exist code of RDMA. But we we have to make a new one because we 
cannot register accelerators such as AI operation, encryption or 
compression to the RDMA framework:)

Another problem we tried to address is the way to pin the memory for dma 
operation. The RDMA way to pin the memory cannot avoid the page lost due 
to copy-on-write operation during the memory is used by the device. This 
may not be important to RDMA library. But it is important to accelerator.

Hope this can help the understanding.

Cheers

>
> Hard NAK from RDMA side.
>
> Thanks
>
>> Signed-off-by: Kenneth Lee <liguozhu@hisilicon.com>
>> ---
>>   Documentation/warpdrive/warpdrive.rst       | 260 +++++++
>>   Documentation/warpdrive/wd-arch.svg         | 764 ++++++++++++++++++++
>>   Documentation/warpdrive/wd.svg              | 526 ++++++++++++++
>>   Documentation/warpdrive/wd_q_addr_space.svg | 359 +++++++++
>>   4 files changed, 1909 insertions(+)
>>   create mode 100644 Documentation/warpdrive/warpdrive.rst
>>   create mode 100644 Documentation/warpdrive/wd-arch.svg
>>   create mode 100644 Documentation/warpdrive/wd.svg
>>   create mode 100644 Documentation/warpdrive/wd_q_addr_space.svg
>>
>> diff --git a/Documentation/warpdrive/warpdrive.rst b/Documentation/warpdrive/warpdrive.rst
>> new file mode 100644
>> index 000000000000..ef84d3a2d462
>> --- /dev/null
>> +++ b/Documentation/warpdrive/warpdrive.rst
>> @@ -0,0 +1,260 @@
>> +Introduction of WarpDrive
>> +=========================
>> +
>> +*WarpDrive* is a general accelerator framework for the user application to
>> +access the hardware without going through the kernel in data path.
>> +
>> +It can be used as the quick channel for accelerators, network adaptors or
>> +other hardware for application in user space.
>> +
>> +This may make some implementation simpler.  E.g.  you can reuse most of the
>> +*netdev* driver in kernel and just share some ring buffer to the user space
>> +driver for *DPDK* [4] or *ODP* [5]. Or you can combine the RSA accelerator with
>> +the *netdev* in the user space as a https reversed proxy, etc.
>> +
>> +*WarpDrive* takes the hardware accelerator as a heterogeneous processor which
>> +can share particular load from the CPU:
>> +
>> +.. image:: wd.svg
>> +        :alt: WarpDrive Concept
>> +
>> +The virtual concept, queue, is used to manage the requests sent to the
>> +accelerator. The application send requests to the queue by writing to some
>> +particular address, while the hardware takes the requests directly from the
>> +address and send feedback accordingly.
>> +
>> +The format of the queue may differ from hardware to hardware. But the
>> +application need not to make any system call for the communication.
>> +
>> +*WarpDrive* tries to create a shared virtual address space for all involved
>> +accelerators. Within this space, the requests sent to queue can refer to any
>> +virtual address, which will be valid to the application and all involved
>> +accelerators.
>> +
>> +The name *WarpDrive* is simply a cool and general name meaning the framework
>> +makes the application faster. It includes general user library, kernel
>> +management module and drivers for the hardware. In kernel, the management
>> +module is called *uacce*, meaning "Unified/User-space-access-intended
>> +Accelerator Framework".
>> +
>> +
>> +How does it work
>> +================
>> +
>> +*WarpDrive* uses *mmap* and *IOMMU* to play the trick.
>> +
>> +*Uacce* creates a chrdev for the device registered to it. A "queue" will be
>> +created when the chrdev is opened. The application access the queue by mmap
>> +different address region of the queue file.
>> +
>> +The following figure demonstrated the queue file address space:
>> +
>> +.. image:: wd_q_addr_space.svg
>> +        :alt: WarpDrive Queue Address Space
>> +
>> +The first region of the space, device region, is used for the application to
>> +write request or read answer to or from the hardware.
>> +
>> +Normally, there can be three types of device regions mmio and memory regions.
>> +It is recommended to use common memory for request/answer descriptors and use
>> +the mmio space for device notification, such as doorbell. But of course, this
>> +is all up to the interface designer.
>> +
>> +There can be two types of device memory regions, kernel-only and user-shared.
>> +This will be explained in the "kernel APIs" section.
>> +
>> +The Static Share Virtual Memory region is necessary only when the device IOMMU
>> +does not support "Share Virtual Memory". This will be explained after the
>> +*IOMMU* idea.
>> +
>> +
>> +Architecture
>> +------------
>> +
>> +The full *WarpDrive* architecture is represented in the following class
>> +diagram:
>> +
>> +.. image:: wd-arch.svg
>> +        :alt: WarpDrive Architecture
>> +
>> +
>> +The user API
>> +------------
>> +
>> +We adopt a polling style interface in the user space: ::
>> +
>> +        int wd_request_queue(struct wd_queue *q);
>> +        void wd_release_queue(struct wd_queue *q);
>> +
>> +        int wd_send(struct wd_queue *q, void *req);
>> +        int wd_recv(struct wd_queue *q, void **req);
>> +        int wd_recv_sync(struct wd_queue *q, void **req);
>> +        void wd_flush(struct wd_queue *q);
>> +
>> +wd_recv_sync() is a wrapper to its non-sync version. It will trapped into
>> +kernel and waits until the queue become available.
>> +
>> +If the queue do not support SVA/SVM. The following helper function
>> +can be used to create Static Virtual Share Memory: ::
>> +
>> +        void *wd_preserve_share_memory(struct wd_queue *q, size_t size);
>> +
>> +The user API is not mandatory. It is simply a suggestion and hint what the
>> +kernel interface is supposed to support.
>> +
>> +
>> +The user driver
>> +---------------
>> +
>> +The queue file mmap space will need a user driver to wrap the communication
>> +protocol. *UACCE* provides some attributes in sysfs for the user driver to
>> +match the right accelerator accordingly.
>> +
>> +The *UACCE* device attribute is under the following directory:
>> +
>> +/sys/class/uacce/<dev-name>/params
>> +
>> +The following attributes is supported:
>> +
>> +nr_queue_remained (ro)
>> +        number of queue remained
>> +
>> +api_version (ro)
>> +        a string to identify the queue mmap space format and its version
>> +
>> +device_attr (ro)
>> +        attributes of the device, see UACCE_DEV_xxx flag defined in uacce.h
>> +
>> +numa_node (ro)
>> +        id of numa node
>> +
>> +priority (rw)
>> +        Priority or the device, bigger is higher
>> +
>> +(This is not yet implemented in RFC version)
>> +
>> +
>> +The kernel API
>> +--------------
>> +
>> +The *uacce* kernel API is defined in uacce.h. If the hardware support SVM/SVA,
>> +The driver need only the following API functions: ::
>> +
>> +        int uacce_register(uacce);
>> +        void uacce_unregister(uacce);
>> +        void uacce_wake_up(q);
>> +
>> +*uacce_wake_up* is used to notify the process who epoll() on the queue file.
>> +
>> +According to the IOMMU capability, *uacce* categories the devices as follow:
>> +
>> +UACCE_DEV_NOIOMMU
>> +        The device has no IOMMU. The user process cannot use VA on the hardware
>> +        This mode is not recommended.
>> +
>> +UACCE_DEV_SVA (UACCE_DEV_PASID | UACCE_DEV_FAULT_FROM_DEV)
>> +        The device has IOMMU which can share the same page table with user
>> +        process
>> +
>> +UACCE_DEV_SHARE_DOMAIN
>> +        The device has IOMMU which has no multiple page table and device page
>> +        fault support
>> +
>> +If the device works in mode other than UACCE_DEV_NOIOMMU, *uacce* will set its
>> +IOMMU to IOMMU_DOMAIN_UNMANAGED. So the driver must not use any kernel
>> +DMA API but the following ones from *uacce* instead: ::
>> +
>> +        uacce_dma_map(q, va, size, prot);
>> +        uacce_dma_unmap(q, va, size, prot);
>> +
>> +*uacce_dma_map/unmap* is valid only for UACCE_DEV_SVA device. It creates a
>> +particular PASID and page table for the kernel in the IOMMU (Not yet
>> +implemented in the RFC)
>> +
>> +For the UACCE_DEV_SHARE_DOMAIN device, uacce_dma_map/unmap is not valid.
>> +*Uacce* call back start_queue only when the DUS and DKO region is mmapped. The
>> +accelerator driver must use those dma buffer, via uacce_queue->qfrs[], on
>> +start_queue call back. The size of the queue file region is defined by
>> +uacce->ops->qf_pg_start[].
>> +
>> +We have to do it this way because most of current IOMMU cannot support the
>> +kernel and user virtual address at the same time. So we have to let them both
>> +share the same user virtual address space.
>> +
>> +If the device have to support kernel and user at the same time, both kernel
>> +and the user should use these DMA API. This is not convenient. A better
>> +solution is to change the future DMA/IOMMU design to let them separate the
>> +address space between the user and kernel space. But it is not going to be in
>> +a short time.
>> +
>> +
>> +Multiple processes support
>> +==========================
>> +
>> +In the latest mainline kernel (4.19) when this document is written, the IOMMU
>> +subsystem do not support multiple process page tables yet.
>> +
>> +Most IOMMU hardware implementation support multi-process with the concept
>> +of PASID. But they may use different name, e.g. it is call sub-stream-id in
>> +SMMU of ARM. With PASID or similar design, multi page table can be added to
>> +the IOMMU and referred by its PASID.
>> +
>> +*JPB* has a patchset to enable this[1]_. We have tested it with our hardware
>> +(which is known as *D06*). It works well. *WarpDrive* rely on them to support
>> +UACCE_DEV_SVA. If it is not enabled, *WarpDrive* can still work. But it
>> +support only one process, the device will be set to UACCE_DEV_SHARE_DOMAIN
>> +even it is set to UACCE_DEV_SVA initially.
>> +
>> +Static Share Virtual Memory is mainly used by UACCE_DEV_SHARE_DOMAIN device.
>> +
>> +
>> +Legacy Mode Support
>> +===================
>> +For the hardware without IOMMU, WarpDrive can still work, the only problem is
>> +VA cannot be used in the device. The driver should adopt another strategy for
>> +the shared memory. It is only for testing, and not recommended.
>> +
>> +
>> +The Folk Scenario
>> +=================
>> +For a process with allocated queues and shared memory, what happen if it forks
>> +a child?
>> +
>> +The fd of the queue will be duplicated on folk, so the child can send request
>> +to the same queue as its parent. But the requests which is sent from processes
>> +except for the one who open the queue will be blocked.
>> +
>> +It is recommended to add O_CLOEXEC to the queue file.
>> +
>> +The queue mmap space has a VM_DONTCOPY in its VMA. So the child will lost all
>> +those VMAs.
>> +
>> +This is why *WarpDrive* does not adopt the mode used in *VFIO* and *InfiniBand*.
>> +Both solutions can set any user pointer for hardware sharing. But they cannot
>> +support fork when the dma is in process. Or the "Copy-On-Write" procedure will
>> +make the parent process lost its physical pages.
>> +
>> +
>> +The Sample Code
>> +===============
>> +There is a sample user land implementation with a simple driver for Hisilicon
>> +Hi1620 ZIP Accelerator.
>> +
>> +To test, do the following in samples/warpdrive (for the case of PC host): ::
>> +        ./autogen.sh
>> +        ./conf.sh       # or simply ./configure if you build on target system
>> +        make
>> +
>> +Then you can get test_hisi_zip in the test subdirectory. Copy it to the target
>> +system and make sure the hisi_zip driver is enabled (the major and minor of
>> +the uacce chrdev can be gotten from the dmesg or sysfs), and run: ::
>> +        mknod /dev/ua1 c <major> <minior>
>> +        test/test_hisi_zip -z < data > data.zip
>> +        test/test_hisi_zip -g < data > data.gzip
>> +
>> +
>> +References
>> +==========
>> +.. [1] https://patchwork.kernel.org/patch/10394851/
>> +
>> +.. vim: tw=78
>> diff --git a/Documentation/warpdrive/wd-arch.svg b/Documentation/warpdrive/wd-arch.svg
>> new file mode 100644
>> index 000000000000..e59934188443
>> --- /dev/null
>> +++ b/Documentation/warpdrive/wd-arch.svg
>> @@ -0,0 +1,764 @@
>> +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
>> +<!-- Created with Inkscape (http://www.inkscape.org/) -->
>> +
>> +<svg
>> +   xmlns:dc="http://purl.org/dc/elements/1.1/"
>> +   xmlns:cc="http://creativecommons.org/ns#"
>> +   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
>> +   xmlns:svg="http://www.w3.org/2000/svg"
>> +   xmlns="http://www.w3.org/2000/svg"
>> +   xmlns:xlink="http://www.w3.org/1999/xlink"
>> +   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
>> +   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
>> +   width="210mm"
>> +   height="193mm"
>> +   viewBox="0 0 744.09449 683.85823"
>> +   id="svg2"
>> +   version="1.1"
>> +   inkscape:version="0.92.3 (2405546, 2018-03-11)"
>> +   sodipodi:docname="wd-arch.svg">
>> +  <defs
>> +     id="defs4">
>> +    <linearGradient
>> +       inkscape:collect="always"
>> +       id="linearGradient6830">
>> +      <stop
>> +         style="stop-color:#000000;stop-opacity:1;"
>> +         offset="0"
>> +         id="stop6832" />
>> +      <stop
>> +         style="stop-color:#000000;stop-opacity:0;"
>> +         offset="1"
>> +         id="stop6834" />
>> +    </linearGradient>
>> +    <linearGradient
>> +       inkscape:collect="always"
>> +       xlink:href="#linearGradient5026"
>> +       id="linearGradient5032"
>> +       x1="353"
>> +       y1="211.3622"
>> +       x2="565.5"
>> +       y2="174.8622"
>> +       gradientUnits="userSpaceOnUse"
>> +       gradientTransform="translate(-89.949614,405.94594)" />
>> +    <linearGradient
>> +       inkscape:collect="always"
>> +       id="linearGradient5026">
>> +      <stop
>> +         style="stop-color:#f2f2f2;stop-opacity:1;"
>> +         offset="0"
>> +         id="stop5028" />
>> +      <stop
>> +         style="stop-color:#f2f2f2;stop-opacity:0;"
>> +         offset="1"
>> +         id="stop5030" />
>> +    </linearGradient>
>> +    <filter
>> +       inkscape:collect="always"
>> +       style="color-interpolation-filters:sRGB"
>> +       id="filter4169-3"
>> +       x="-0.031597666"
>> +       width="1.0631953"
>> +       y="-0.099812768"
>> +       height="1.1996255">
>> +      <feGaussianBlur
>> +         inkscape:collect="always"
>> +         stdDeviation="1.3307599"
>> +         id="feGaussianBlur4171-6" />
>> +    </filter>
>> +    <linearGradient
>> +       inkscape:collect="always"
>> +       xlink:href="#linearGradient5026"
>> +       id="linearGradient5032-1"
>> +       x1="353"
>> +       y1="211.3622"
>> +       x2="565.5"
>> +       y2="174.8622"
>> +       gradientUnits="userSpaceOnUse"
>> +       gradientTransform="translate(175.77842,400.29111)" />
>> +    <filter
>> +       inkscape:collect="always"
>> +       style="color-interpolation-filters:sRGB"
>> +       id="filter4169-3-0"
>> +       x="-0.031597666"
>> +       width="1.0631953"
>> +       y="-0.099812768"
>> +       height="1.1996255">
>> +      <feGaussianBlur
>> +         inkscape:collect="always"
>> +         stdDeviation="1.3307599"
>> +         id="feGaussianBlur4171-6-9" />
>> +    </filter>
>> +    <marker
>> +       markerWidth="18.960653"
>> +       markerHeight="11.194658"
>> +       refX="9.4803267"
>> +       refY="5.5973287"
>> +       orient="auto"
>> +       id="marker4613">
>> +      <rect
>> +         y="-5.1589785"
>> +         x="5.8504119"
>> +         height="10.317957"
>> +         width="10.317957"
>> +         id="rect4212"
>> +         style="fill:#ffffff;stroke:#000000;stroke-width:0.69143367;stroke-miterlimit:4;stroke-dasharray:none"
>> +         transform="matrix(0.86111274,0.50841405,-0.86111274,0.50841405,0,0)">
>> +        <title
>> +           id="title4262">generation</title>
>> +      </rect>
>> +    </marker>
>> +    <marker
>> +       markerWidth="11.227358"
>> +       markerHeight="12.355258"
>> +       refX="10"
>> +       refY="6.177629"
>> +       orient="auto"
>> +       id="marker4825">
>> +      <path
>> +         inkscape:connector-curvature="0"
>> +         id="path4757"
>> +         d="M 0.42024733,0.42806444 10.231357,6.3500844 0.24347733,11.918544"
>> +         style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
>> +    </marker>
>> +    <marker
>> +       markerWidth="11.227358"
>> +       markerHeight="12.355258"
>> +       refX="10"
>> +       refY="6.177629"
>> +       orient="auto"
>> +       id="marker4825-6">
>> +      <path
>> +         inkscape:connector-curvature="0"
>> +         id="path4757-1"
>> +         d="M 0.42024733,0.42806444 10.231357,6.3500844 0.24347733,11.918544"
>> +         style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
>> +    </marker>
>> +    <linearGradient
>> +       inkscape:collect="always"
>> +       xlink:href="#linearGradient5026"
>> +       id="linearGradient5032-3-9"
>> +       x1="353"
>> +       y1="211.3622"
>> +       x2="565.5"
>> +       y2="174.8622"
>> +       gradientUnits="userSpaceOnUse"
>> +       gradientTransform="matrix(1.2452511,0,0,0.98513016,-190.95632,540.33156)" />
>> +    <filter
>> +       inkscape:collect="always"
>> +       style="color-interpolation-filters:sRGB"
>> +       id="filter4169-3-5-8"
>> +       x="-0.031597666"
>> +       width="1.0631953"
>> +       y="-0.099812768"
>> +       height="1.1996255">
>> +      <feGaussianBlur
>> +         inkscape:collect="always"
>> +         stdDeviation="1.3307599"
>> +         id="feGaussianBlur4171-6-3-9" />
>> +    </filter>
>> +    <marker
>> +       markerWidth="11.227358"
>> +       markerHeight="12.355258"
>> +       refX="10"
>> +       refY="6.177629"
>> +       orient="auto"
>> +       id="marker4825-6-2">
>> +      <path
>> +         inkscape:connector-curvature="0"
>> +         id="path4757-1-9"
>> +         d="M 0.42024733,0.42806444 10.231357,6.3500844 0.24347733,11.918544"
>> +         style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
>> +    </marker>
>> +    <marker
>> +       markerWidth="11.227358"
>> +       markerHeight="12.355258"
>> +       refX="10"
>> +       refY="6.177629"
>> +       orient="auto"
>> +       id="marker4825-6-2-1">
>> +      <path
>> +         inkscape:connector-curvature="0"
>> +         id="path4757-1-9-9"
>> +         d="M 0.42024733,0.42806444 10.231357,6.3500844 0.24347733,11.918544"
>> +         style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
>> +    </marker>
>> +    <linearGradient
>> +       inkscape:collect="always"
>> +       xlink:href="#linearGradient5026"
>> +       id="linearGradient5032-3-9-7"
>> +       x1="353"
>> +       y1="211.3622"
>> +       x2="565.5"
>> +       y2="174.8622"
>> +       gradientUnits="userSpaceOnUse"
>> +       gradientTransform="matrix(1.3742742,0,0,0.97786398,-234.52617,654.63367)" />
>> +    <filter
>> +       inkscape:collect="always"
>> +       style="color-interpolation-filters:sRGB"
>> +       id="filter4169-3-5-8-5"
>> +       x="-0.031597666"
>> +       width="1.0631953"
>> +       y="-0.099812768"
>> +       height="1.1996255">
>> +      <feGaussianBlur
>> +         inkscape:collect="always"
>> +         stdDeviation="1.3307599"
>> +         id="feGaussianBlur4171-6-3-9-0" />
>> +    </filter>
>> +    <marker
>> +       markerWidth="11.227358"
>> +       markerHeight="12.355258"
>> +       refX="10"
>> +       refY="6.177629"
>> +       orient="auto"
>> +       id="marker4825-6-2-6">
>> +      <path
>> +         inkscape:connector-curvature="0"
>> +         id="path4757-1-9-1"
>> +         d="M 0.42024733,0.42806444 10.231357,6.3500844 0.24347733,11.918544"
>> +         style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
>> +    </marker>
>> +    <linearGradient
>> +       inkscape:collect="always"
>> +       xlink:href="#linearGradient5026"
>> +       id="linearGradient5032-3-9-4"
>> +       x1="353"
>> +       y1="211.3622"
>> +       x2="565.5"
>> +       y2="174.8622"
>> +       gradientUnits="userSpaceOnUse"
>> +       gradientTransform="matrix(1.3742912,0,0,2.0035845,-468.34428,342.56603)" />
>> +    <filter
>> +       inkscape:collect="always"
>> +       style="color-interpolation-filters:sRGB"
>> +       id="filter4169-3-5-8-54"
>> +       x="-0.031597666"
>> +       width="1.0631953"
>> +       y="-0.099812768"
>> +       height="1.1996255">
>> +      <feGaussianBlur
>> +         inkscape:collect="always"
>> +         stdDeviation="1.3307599"
>> +         id="feGaussianBlur4171-6-3-9-7" />
>> +    </filter>
>> +    <marker
>> +       markerWidth="11.227358"
>> +       markerHeight="12.355258"
>> +       refX="10"
>> +       refY="6.177629"
>> +       orient="auto"
>> +       id="marker4825-6-2-1-8">
>> +      <path
>> +         inkscape:connector-curvature="0"
>> +         id="path4757-1-9-9-6"
>> +         d="M 0.42024733,0.42806444 10.231357,6.3500844 0.24347733,11.918544"
>> +         style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
>> +    </marker>
>> +    <marker
>> +       markerWidth="11.227358"
>> +       markerHeight="12.355258"
>> +       refX="10"
>> +       refY="6.177629"
>> +       orient="auto"
>> +       id="marker4825-6-2-1-8-8">
>> +      <path
>> +         inkscape:connector-curvature="0"
>> +         id="path4757-1-9-9-6-9"
>> +         d="M 0.42024733,0.42806444 10.231357,6.3500844 0.24347733,11.918544"
>> +         style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
>> +    </marker>
>> +    <marker
>> +       markerWidth="11.227358"
>> +       markerHeight="12.355258"
>> +       refX="10"
>> +       refY="6.177629"
>> +       orient="auto"
>> +       id="marker4825-6-0">
>> +      <path
>> +         inkscape:connector-curvature="0"
>> +         id="path4757-1-93"
>> +         d="M 0.42024733,0.42806444 10.231357,6.3500844 0.24347733,11.918544"
>> +         style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
>> +    </marker>
>> +    <marker
>> +       markerWidth="11.227358"
>> +       markerHeight="12.355258"
>> +       refX="10"
>> +       refY="6.177629"
>> +       orient="auto"
>> +       id="marker4825-6-0-2">
>> +      <path
>> +         inkscape:connector-curvature="0"
>> +         id="path4757-1-93-6"
>> +         d="M 0.42024733,0.42806444 10.231357,6.3500844 0.24347733,11.918544"
>> +         style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
>> +    </marker>
>> +    <filter
>> +       inkscape:collect="always"
>> +       style="color-interpolation-filters:sRGB"
>> +       id="filter5382"
>> +       x="-0.089695387"
>> +       width="1.1793908"
>> +       y="-0.10052069"
>> +       height="1.2010413">
>> +      <feGaussianBlur
>> +         inkscape:collect="always"
>> +         stdDeviation="0.86758925"
>> +         id="feGaussianBlur5384" />
>> +    </filter>
>> +    <linearGradient
>> +       inkscape:collect="always"
>> +       xlink:href="#linearGradient6830"
>> +       id="linearGradient6836"
>> +       x1="362.73923"
>> +       y1="700.04059"
>> +       x2="340.4751"
>> +       y2="678.25488"
>> +       gradientUnits="userSpaceOnUse"
>> +       gradientTransform="translate(-23.771026,-135.76835)" />
>> +    <marker
>> +       markerWidth="11.227358"
>> +       markerHeight="12.355258"
>> +       refX="10"
>> +       refY="6.177629"
>> +       orient="auto"
>> +       id="marker4825-6-2-6-2">
>> +      <path
>> +         inkscape:connector-curvature="0"
>> +         id="path4757-1-9-1-9"
>> +         d="M 0.42024733,0.42806444 10.231357,6.3500844 0.24347733,11.918544"
>> +         style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
>> +    </marker>
>> +    <linearGradient
>> +       inkscape:collect="always"
>> +       xlink:href="#linearGradient5026"
>> +       id="linearGradient5032-3-9-7-3"
>> +       x1="353"
>> +       y1="211.3622"
>> +       x2="565.5"
>> +       y2="174.8622"
>> +       gradientUnits="userSpaceOnUse"
>> +       gradientTransform="matrix(1.3742742,0,0,0.97786395,-57.357186,649.55786)" />
>> +    <filter
>> +       inkscape:collect="always"
>> +       style="color-interpolation-filters:sRGB"
>> +       id="filter4169-3-5-8-5-0"
>> +       x="-0.031597666"
>> +       width="1.0631953"
>> +       y="-0.099812768"
>> +       height="1.1996255">
>> +      <feGaussianBlur
>> +         inkscape:collect="always"
>> +         stdDeviation="1.3307599"
>> +         id="feGaussianBlur4171-6-3-9-0-2" />
>> +    </filter>
>> +    <marker
>> +       markerWidth="11.227358"
>> +       markerHeight="12.355258"
>> +       refX="10"
>> +       refY="6.177629"
>> +       orient="auto"
>> +       id="marker4825-6-2-1-1">
>> +      <path
>> +         inkscape:connector-curvature="0"
>> +         id="path4757-1-9-9-0"
>> +         d="M 0.42024733,0.42806444 10.231357,6.3500844 0.24347733,11.918544"
>> +         style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
>> +    </marker>
>> +  </defs>
>> +  <sodipodi:namedview
>> +     id="base"
>> +     pagecolor="#ffffff"
>> +     bordercolor="#666666"
>> +     borderopacity="1.0"
>> +     inkscape:pageopacity="0.0"
>> +     inkscape:pageshadow="2"
>> +     inkscape:zoom="0.98994949"
>> +     inkscape:cx="222.32868"
>> +     inkscape:cy="370.44492"
>> +     inkscape:document-units="px"
>> +     inkscape:current-layer="layer1"
>> +     showgrid="false"
>> +     inkscape:window-width="1916"
>> +     inkscape:window-height="1033"
>> +     inkscape:window-x="0"
>> +     inkscape:window-y="22"
>> +     inkscape:window-maximized="0"
>> +     fit-margin-right="0.3"
>> +     inkscape:snap-global="false" />
>> +  <metadata
>> +     id="metadata7">
>> +    <rdf:RDF>
>> +      <cc:Work
>> +         rdf:about="">
>> +        <dc:format>image/svg+xml</dc:format>
>> +        <dc:type
>> +           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
>> +        <dc:title />
>> +      </cc:Work>
>> +    </rdf:RDF>
>> +  </metadata>
>> +  <g
>> +     inkscape:label="Layer 1"
>> +     inkscape:groupmode="layer"
>> +     id="layer1"
>> +     transform="translate(0,-368.50374)">
>> +    <rect
>> +       style="fill:#000000;stroke:#000000;stroke-width:0.6465112;filter:url(#filter4169-3)"
>> +       id="rect4136-3-6"
>> +       width="101.07784"
>> +       height="31.998148"
>> +       x="283.01144"
>> +       y="588.80896" />
>> +    <rect
>> +       style="fill:url(#linearGradient5032);fill-opacity:1;stroke:#000000;stroke-width:0.6465112"
>> +       id="rect4136-2"
>> +       width="101.07784"
>> +       height="31.998148"
>> +       x="281.63498"
>> +       y="586.75739" />
>> +    <text
>> +       xml:space="preserve"
>> +       style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
>> +       x="294.21747"
>> +       y="612.50073"
>> +       id="text4138-6"><tspan
>> +         sodipodi:role="line"
>> +         id="tspan4140-1"
>> +         x="294.21747"
>> +         y="612.50073"
>> +         style="font-size:15px;line-height:1.25">WarpDrive</tspan></text>
>> +    <rect
>> +       style="fill:#000000;stroke:#000000;stroke-width:0.6465112;filter:url(#filter4169-3-0)"
>> +       id="rect4136-3-6-3"
>> +       width="101.07784"
>> +       height="31.998148"
>> +       x="548.7395"
>> +       y="583.15417" />
>> +    <rect
>> +       style="fill:url(#linearGradient5032-1);fill-opacity:1;stroke:#000000;stroke-width:0.6465112"
>> +       id="rect4136-2-60"
>> +       width="101.07784"
>> +       height="31.998148"
>> +       x="547.36304"
>> +       y="581.1026" />
>> +    <text
>> +       xml:space="preserve"
>> +       style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
>> +       x="557.83484"
>> +       y="602.32745"
>> +       id="text4138-6-6"><tspan
>> +         sodipodi:role="line"
>> +         id="tspan4140-1-2"
>> +         x="557.83484"
>> +         y="602.32745"
>> +         style="font-size:15px;line-height:1.25">user_driver</tspan></text>
>> +    <path
>> +       style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker4613)"
>> +       d="m 547.36304,600.78954 -156.58203,0.0691"
>> +       id="path4855"
>> +       inkscape:connector-curvature="0"
>> +       sodipodi:nodetypes="cc" />
>> +    <rect
>> +       style="fill:#000000;stroke:#000000;stroke-width:0.6465112;filter:url(#filter4169-3-5-8)"
>> +       id="rect4136-3-6-5-7"
>> +       width="101.07784"
>> +       height="31.998148"
>> +       x="128.74678"
>> +       y="80.648842"
>> +       transform="matrix(1.2452511,0,0,0.98513016,113.15182,641.02594)" />
>> +    <rect
>> +       style="fill:url(#linearGradient5032-3-9);fill-opacity:1;stroke:#000000;stroke-width:0.71606314"
>> +       id="rect4136-2-6-3"
>> +       width="125.86729"
>> +       height="31.522341"
>> +       x="271.75983"
>> +       y="718.45435" />
>> +    <text
>> +       xml:space="preserve"
>> +       style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
>> +       x="309.13705"
>> +       y="745.55371"
>> +       id="text4138-6-2-6"><tspan
>> +         sodipodi:role="line"
>> +         id="tspan4140-1-9-1"
>> +         x="309.13705"
>> +         y="745.55371"
>> +         style="font-size:15px;line-height:1.25">uacce</tspan></text>
>> +    <path
>> +       style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker4825-6-2)"
>> +       d="m 329.57309,619.72453 5.0373,97.14447"
>> +       id="path4661-3"
>> +       inkscape:connector-curvature="0"
>> +       sodipodi:nodetypes="cc" />
>> +    <path
>> +       style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker4825-6-2-1)"
>> +       d="m 342.57219,830.63108 -5.67699,-79.2841"
>> +       id="path4661-3-4"
>> +       inkscape:connector-curvature="0"
>> +       sodipodi:nodetypes="cc" />
>> +    <rect
>> +       style="fill:#000000;stroke:#000000;stroke-width:0.6465112;filter:url(#filter4169-3-5-8-5)"
>> +       id="rect4136-3-6-5-7-3"
>> +       width="101.07784"
>> +       height="31.998148"
>> +       x="128.74678"
>> +       y="80.648842"
>> +       transform="matrix(1.3742742,0,0,0.97786398,101.09126,754.58534)" />
>> +    <rect
>> +       style="fill:url(#linearGradient5032-3-9-7);fill-opacity:1;stroke:#000000;stroke-width:0.74946606"
>> +       id="rect4136-2-6-3-6"
>> +       width="138.90866"
>> +       height="31.289837"
>> +       x="276.13297"
>> +       y="831.44263" />
>> +    <text
>> +       xml:space="preserve"
>> +       style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
>> +       x="295.67819"
>> +       y="852.98224"
>> +       id="text4138-6-2-6-1"><tspan
>> +         sodipodi:role="line"
>> +         id="tspan4140-1-9-1-0"
>> +         x="295.67819"
>> +         y="852.98224"
>> +         style="font-size:15px;line-height:1.25">Device Driver</tspan></text>
>> +    <path
>> +       style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker4825-6-2-6)"
>> +       d="m 623.05084,615.00104 0.51369,333.80219"
>> +       id="path4661-3-5"
>> +       inkscape:connector-curvature="0"
>> +       sodipodi:nodetypes="cc" />
>> +    <text
>> +       xml:space="preserve"
>> +       style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
>> +       x="392.63568"
>> +       y="660.83667"
>> +       id="text4138-6-2-6-1-6-2-5"><tspan
>> +         sodipodi:role="line"
>> +         x="392.63568"
>> +         y="660.83667"
>> +         id="tspan4305"
>> +         style="font-size:15px;line-height:1.25">&lt;&lt;anom_file&gt;&gt;</tspan><tspan
>> +         sodipodi:role="line"
>> +         x="392.63568"
>> +         y="679.58667"
>> +         style="font-size:15px;line-height:1.25"
>> +         id="tspan1139">Queue FD</tspan></text>
>> +    <text
>> +       xml:space="preserve"
>> +       style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
>> +       x="389.92969"
>> +       y="587.44836"
>> +       id="text4138-6-2-6-1-6-2-56"><tspan
>> +         sodipodi:role="line"
>> +         id="tspan4140-1-9-1-0-3-0-9"
>> +         x="389.92969"
>> +         y="587.44836"
>> +         style="font-size:15px;line-height:1.25">1</tspan></text>
>> +    <text
>> +       xml:space="preserve"
>> +       style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
>> +       x="528.64813"
>> +       y="600.08429"
>> +       id="text4138-6-2-6-1-6-3"><tspan
>> +         sodipodi:role="line"
>> +         id="tspan4140-1-9-1-0-3-7"
>> +         x="528.64813"
>> +         y="600.08429"
>> +         style="font-size:15px;line-height:1.25">*</tspan></text>
>> +    <rect
>> +       style="fill:#000000;stroke:#000000;stroke-width:0.6465112;filter:url(#filter4169-3-5-8-54)"
>> +       id="rect4136-3-6-5-7-4"
>> +       width="101.07784"
>> +       height="31.998148"
>> +       x="128.74678"
>> +       y="80.648842"
>> +       transform="matrix(1.3745874,0,0,1.8929066,-132.7754,556.04505)" />
>> +    <rect
>> +       style="fill:url(#linearGradient5032-3-9-4);fill-opacity:1;stroke:#000000;stroke-width:1.07280123"
>> +       id="rect4136-2-6-3-4"
>> +       width="138.91039"
>> +       height="64.111"
>> +       x="42.321312"
>> +       y="704.8371" />
>> +    <text
>> +       xml:space="preserve"
>> +       style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
>> +       x="110.30745"
>> +       y="722.94025"
>> +       id="text4138-6-2-6-3"><tspan
>> +         sodipodi:role="line"
>> +         x="111.99202"
>> +         y="722.94025"
>> +         id="tspan4366"
>> +         style="font-size:15px;line-height:1.25;text-align:center;text-anchor:middle">other standard </tspan><tspan
>> +         sodipodi:role="line"
>> +         x="110.30745"
>> +         y="741.69025"
>> +         id="tspan4368"
>> +         style="font-size:15px;line-height:1.25;text-align:center;text-anchor:middle">framework</tspan><tspan
>> +         sodipodi:role="line"
>> +         x="110.30745"
>> +         y="760.44025"
>> +         style="font-size:15px;line-height:1.25;text-align:center;text-anchor:middle"
>> +         id="tspan6840">(crypto/nic/others)</tspan></text>
>> +    <path
>> +       style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker4825-6-2-1-8)"
>> +       d="M 276.29661,849.04109 134.04449,771.90853"
>> +       id="path4661-3-4-8"
>> +       inkscape:connector-curvature="0"
>> +       sodipodi:nodetypes="cc" />
>> +    <text
>> +       xml:space="preserve"
>> +       style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
>> +       x="313.70813"
>> +       y="730.06366"
>> +       id="text4138-6-2-6-36"><tspan
>> +         sodipodi:role="line"
>> +         id="tspan4140-1-9-1-7"
>> +         x="313.70813"
>> +         y="730.06366"
>> +         style="font-size:10px;line-height:1.25">&lt;&lt;lkm&gt;&gt;</tspan></text>
>> +    <text
>> +       xml:space="preserve"
>> +       style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;text-align:start;letter-spacing:0px;word-spacing:0px;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
>> +       x="259.53165"
>> +       y="797.8056"
>> +       id="text4138-6-2-6-1-6-2-5-7-5"><tspan
>> +         sodipodi:role="line"
>> +         x="259.53165"
>> +         y="797.8056"
>> +         style="font-size:15px;line-height:1.25;text-align:start;text-anchor:start"
>> +         id="tspan2357">uacce register api</tspan></text>
>> +    <text
>> +       xml:space="preserve"
>> +       style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
>> +       x="29.145819"
>> +       y="833.44244"
>> +       id="text4138-6-2-6-1-6-2-5-7-5-2"><tspan
>> +         sodipodi:role="line"
>> +         x="29.145819"
>> +         y="833.44244"
>> +         id="tspan4301"
>> +         style="font-size:15px;line-height:1.25">register to other subsystem</tspan></text>
>> +    <text
>> +       xml:space="preserve"
>> +       style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
>> +       x="301.20813"
>> +       y="597.29437"
>> +       id="text4138-6-2-6-36-1"><tspan
>> +         sodipodi:role="line"
>> +         id="tspan4140-1-9-1-7-2"
>> +         x="301.20813"
>> +         y="597.29437"
>> +         style="font-size:10px;line-height:1.25">&lt;&lt;user_lib&gt;&gt;</tspan></text>
>> +    <text
>> +       xml:space="preserve"
>> +       style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
>> +       x="615.9505"
>> +       y="739.44012"
>> +       id="text4138-6-2-6-1-6-2-5-3"><tspan
>> +         sodipodi:role="line"
>> +         x="615.9505"
>> +         y="739.44012"
>> +         id="tspan4274-7"
>> +         style="font-size:15px;line-height:1.25">mmapped memory r/w interface</tspan></text>
>> +    <text
>> +       xml:space="preserve"
>> +       style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
>> +       x="371.01291"
>> +       y="529.23682"
>> +       id="text4138-6-2-6-1-6-2-5-36"><tspan
>> +         sodipodi:role="line"
>> +         x="371.01291"
>> +         y="529.23682"
>> +         id="tspan4305-3"
>> +         style="font-size:15px;line-height:1.25">wd user api</tspan></text>
>> +    <path
>> +       style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
>> +       d="m 328.19325,585.87943 0,-23.57142"
>> +       id="path4348"
>> +       inkscape:connector-curvature="0" />
>> +    <ellipse
>> +       style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0"
>> +       id="path4350"
>> +       cx="328.01468"
>> +       cy="551.95081"
>> +       rx="11.607142"
>> +       ry="10.357142" />
>> +    <path
>> +       style="opacity:0.444;fill:url(#linearGradient6836);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;filter:url(#filter5382)"
>> +       id="path4350-2"
>> +       sodipodi:type="arc"
>> +       sodipodi:cx="329.44327"
>> +       sodipodi:cy="553.37933"
>> +       sodipodi:rx="11.607142"
>> +       sodipodi:ry="10.357142"
>> +       sodipodi:start="0"
>> +       sodipodi:end="6.2509098"
>> +       d="m 341.05041,553.37933 a 11.607142,10.357142 0 0 1 -11.51349,10.35681 11.607142,10.357142 0 0 1 -11.69928,-10.18967 11.607142,10.357142 0 0 1 11.32469,-10.52124 11.607142,10.357142 0 0 1 11.88204,10.01988"
>> +       sodipodi:open="true" />
>> +    <text
>> +       xml:space="preserve"
>> +       style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
>> +       x="619.67596"
>> +       y="978.22363"
>> +       id="text4138-6-2-6-1-6-2-5-36-3"><tspan
>> +         sodipodi:role="line"
>> +         x="619.67596"
>> +         y="978.22363"
>> +         id="tspan4305-3-67"
>> +         style="font-size:15px;line-height:1.25">Device(Hardware)</tspan></text>
>> +    <path
>> +       style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker4825-6-2-6-2)"
>> +       d="m 347.51164,865.4527 193.91929,99.10053"
>> +       id="path4661-3-5-1"
>> +       inkscape:connector-curvature="0"
>> +       sodipodi:nodetypes="cc" />
>> +    <rect
>> +       style="fill:#000000;stroke:#000000;stroke-width:0.6465112;filter:url(#filter4169-3-5-8-5-0)"
>> +       id="rect4136-3-6-5-7-3-1"
>> +       width="101.07784"
>> +       height="31.998148"
>> +       x="128.74678"
>> +       y="80.648842"
>> +       transform="matrix(1.3742742,0,0,0.97786395,278.26025,749.50952)" />
>> +    <rect
>> +       style="fill:url(#linearGradient5032-3-9-7-3);fill-opacity:1;stroke:#000000;stroke-width:0.74946606"
>> +       id="rect4136-2-6-3-6-0"
>> +       width="138.90868"
>> +       height="31.289839"
>> +       x="453.30197"
>> +       y="826.36682" />
>> +    <text
>> +       xml:space="preserve"
>> +       style="font-style:normal;font-weight:normal;font-size:12px;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
>> +       x="493.68158"
>> +       y="847.90643"
>> +       id="text4138-6-2-6-1-5"><tspan
>> +         sodipodi:role="line"
>> +         id="tspan4140-1-9-1-0-1"
>> +         x="493.68158"
>> +         y="847.90643"
>> +         style="font-size:15px;line-height:1.25;stroke-width:1px">IOMMU</tspan></text>
>> +    <path
>> +       style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker4825-6-2-1-1)"
>> +       d="m 389.49372,755.46667 111.75324,68.4507"
>> +       id="path4661-3-4-85"
>> +       inkscape:connector-curvature="0"
>> +       sodipodi:nodetypes="cc" />
>> +    <text
>> +       xml:space="preserve"
>> +       style="font-style:normal;font-weight:normal;font-size:12px;line-height:0%;font-family:sans-serif;text-align:start;letter-spacing:0px;word-spacing:0px;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
>> +       x="427.70282"
>> +       y="776.91418"
>> +       id="text4138-6-2-6-1-6-2-5-7-5-0"><tspan
>> +         sodipodi:role="line"
>> +         x="427.70282"
>> +         y="776.91418"
>> +         style="font-size:15px;line-height:1.25;text-align:start;text-anchor:start;stroke-width:1px"
>> +         id="tspan2357-6">manage the driver iommu state</tspan></text>
>> +  </g>
>> +</svg>
>> diff --git a/Documentation/warpdrive/wd.svg b/Documentation/warpdrive/wd.svg
>> new file mode 100644
>> index 000000000000..87ab92ebfbc6
>> --- /dev/null
>> +++ b/Documentation/warpdrive/wd.svg
>> @@ -0,0 +1,526 @@
>> +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
>> +<!-- Created with Inkscape (http://www.inkscape.org/) -->
>> +
>> +<svg
>> +   xmlns:dc="http://purl.org/dc/elements/1.1/"
>> +   xmlns:cc="http://creativecommons.org/ns#"
>> +   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
>> +   xmlns:svg="http://www.w3.org/2000/svg"
>> +   xmlns="http://www.w3.org/2000/svg"
>> +   xmlns:xlink="http://www.w3.org/1999/xlink"
>> +   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
>> +   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
>> +   width="210mm"
>> +   height="116mm"
>> +   viewBox="0 0 744.09449 411.02338"
>> +   id="svg2"
>> +   version="1.1"
>> +   inkscape:version="0.92.3 (2405546, 2018-03-11)"
>> +   sodipodi:docname="wd.svg">
>> +  <defs
>> +     id="defs4">
>> +    <linearGradient
>> +       inkscape:collect="always"
>> +       id="linearGradient5026">
>> +      <stop
>> +         style="stop-color:#f2f2f2;stop-opacity:1;"
>> +         offset="0"
>> +         id="stop5028" />
>> +      <stop
>> +         style="stop-color:#f2f2f2;stop-opacity:0;"
>> +         offset="1"
>> +         id="stop5030" />
>> +    </linearGradient>
>> +    <linearGradient
>> +       inkscape:collect="always"
>> +       xlink:href="#linearGradient5026"
>> +       id="linearGradient5032-3"
>> +       x1="353"
>> +       y1="211.3622"
>> +       x2="565.5"
>> +       y2="174.8622"
>> +       gradientUnits="userSpaceOnUse"
>> +       gradientTransform="matrix(2.7384117,0,0,0.91666329,-952.8283,571.10143)" />
>> +    <filter
>> +       inkscape:collect="always"
>> +       style="color-interpolation-filters:sRGB"
>> +       id="filter4169-3-5"
>> +       x="-0.031597666"
>> +       width="1.0631953"
>> +       y="-0.099812768"
>> +       height="1.1996255">
>> +      <feGaussianBlur
>> +         inkscape:collect="always"
>> +         stdDeviation="1.3307599"
>> +         id="feGaussianBlur4171-6-3" />
>> +    </filter>
>> +    <marker
>> +       markerWidth="18.960653"
>> +       markerHeight="11.194658"
>> +       refX="9.4803267"
>> +       refY="5.5973287"
>> +       orient="auto"
>> +       id="marker4613">
>> +      <rect
>> +         y="-5.1589785"
>> +         x="5.8504119"
>> +         height="10.317957"
>> +         width="10.317957"
>> +         id="rect4212"
>> +         style="fill:#ffffff;stroke:#000000;stroke-width:0.69143367;stroke-miterlimit:4;stroke-dasharray:none"
>> +         transform="matrix(0.86111274,0.50841405,-0.86111274,0.50841405,0,0)">
>> +        <title
>> +           id="title4262">generation</title>
>> +      </rect>
>> +    </marker>
>> +    <marker
>> +       markerWidth="11.227358"
>> +       markerHeight="12.355258"
>> +       refX="10"
>> +       refY="6.177629"
>> +       orient="auto"
>> +       id="marker4825">
>> +      <path
>> +         inkscape:connector-curvature="0"
>> +         id="path4757"
>> +         d="M 0.42024733,0.42806444 10.231357,6.3500844 0.24347733,11.918544"
>> +         style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
>> +    </marker>
>> +    <marker
>> +       markerWidth="11.227358"
>> +       markerHeight="12.355258"
>> +       refX="10"
>> +       refY="6.177629"
>> +       orient="auto"
>> +       id="marker4825-6">
>> +      <path
>> +         inkscape:connector-curvature="0"
>> +         id="path4757-1"
>> +         d="M 0.42024733,0.42806444 10.231357,6.3500844 0.24347733,11.918544"
>> +         style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
>> +    </marker>
>> +    <linearGradient
>> +       inkscape:collect="always"
>> +       xlink:href="#linearGradient5026"
>> +       id="linearGradient5032-3-9"
>> +       x1="353"
>> +       y1="211.3622"
>> +       x2="565.5"
>> +       y2="174.8622"
>> +       gradientUnits="userSpaceOnUse"
>> +       gradientTransform="matrix(1.2452511,0,0,0.98513016,-190.95632,540.33156)" />
>> +    <marker
>> +       markerWidth="11.227358"
>> +       markerHeight="12.355258"
>> +       refX="10"
>> +       refY="6.177629"
>> +       orient="auto"
>> +       id="marker4825-6-2">
>> +      <path
>> +         inkscape:connector-curvature="0"
>> +         id="path4757-1-9"
>> +         d="M 0.42024733,0.42806444 10.231357,6.3500844 0.24347733,11.918544"
>> +         style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
>> +    </marker>
>> +    <marker
>> +       markerWidth="11.227358"
>> +       markerHeight="12.355258"
>> +       refX="10"
>> +       refY="6.177629"
>> +       orient="auto"
>> +       id="marker4825-6-2-1">
>> +      <path
>> +         inkscape:connector-curvature="0"
>> +         id="path4757-1-9-9"
>> +         d="M 0.42024733,0.42806444 10.231357,6.3500844 0.24347733,11.918544"
>> +         style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
>> +    </marker>
>> +    <marker
>> +       markerWidth="11.227358"
>> +       markerHeight="12.355258"
>> +       refX="10"
>> +       refY="6.177629"
>> +       orient="auto"
>> +       id="marker4825-6-2-6">
>> +      <path
>> +         inkscape:connector-curvature="0"
>> +         id="path4757-1-9-1"
>> +         d="M 0.42024733,0.42806444 10.231357,6.3500844 0.24347733,11.918544"
>> +         style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
>> +    </marker>
>> +    <marker
>> +       markerWidth="11.227358"
>> +       markerHeight="12.355258"
>> +       refX="10"
>> +       refY="6.177629"
>> +       orient="auto"
>> +       id="marker4825-6-2-1-8">
>> +      <path
>> +         inkscape:connector-curvature="0"
>> +         id="path4757-1-9-9-6"
>> +         d="M 0.42024733,0.42806444 10.231357,6.3500844 0.24347733,11.918544"
>> +         style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
>> +    </marker>
>> +    <marker
>> +       markerWidth="11.227358"
>> +       markerHeight="12.355258"
>> +       refX="10"
>> +       refY="6.177629"
>> +       orient="auto"
>> +       id="marker4825-6-2-1-8-8">
>> +      <path
>> +         inkscape:connector-curvature="0"
>> +         id="path4757-1-9-9-6-9"
>> +         d="M 0.42024733,0.42806444 10.231357,6.3500844 0.24347733,11.918544"
>> +         style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
>> +    </marker>
>> +    <marker
>> +       markerWidth="11.227358"
>> +       markerHeight="12.355258"
>> +       refX="10"
>> +       refY="6.177629"
>> +       orient="auto"
>> +       id="marker4825-6-0">
>> +      <path
>> +         inkscape:connector-curvature="0"
>> +         id="path4757-1-93"
>> +         d="M 0.42024733,0.42806444 10.231357,6.3500844 0.24347733,11.918544"
>> +         style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
>> +    </marker>
>> +    <marker
>> +       markerWidth="11.227358"
>> +       markerHeight="12.355258"
>> +       refX="10"
>> +       refY="6.177629"
>> +       orient="auto"
>> +       id="marker4825-6-0-2">
>> +      <path
>> +         inkscape:connector-curvature="0"
>> +         id="path4757-1-93-6"
>> +         d="M 0.42024733,0.42806444 10.231357,6.3500844 0.24347733,11.918544"
>> +         style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
>> +    </marker>
>> +    <marker
>> +       markerWidth="11.227358"
>> +       markerHeight="12.355258"
>> +       refX="10"
>> +       refY="6.177629"
>> +       orient="auto"
>> +       id="marker4825-6-2-6-2">
>> +      <path
>> +         inkscape:connector-curvature="0"
>> +         id="path4757-1-9-1-9"
>> +         d="M 0.42024733,0.42806444 10.231357,6.3500844 0.24347733,11.918544"
>> +         style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
>> +    </marker>
>> +    <linearGradient
>> +       inkscape:collect="always"
>> +       xlink:href="#linearGradient5026"
>> +       id="linearGradient5032-3-8"
>> +       x1="353"
>> +       y1="211.3622"
>> +       x2="565.5"
>> +       y2="174.8622"
>> +       gradientUnits="userSpaceOnUse"
>> +       gradientTransform="matrix(1.0104674,0,0,1.0052679,-218.642,661.15448)" />
>> +    <filter
>> +       inkscape:collect="always"
>> +       style="color-interpolation-filters:sRGB"
>> +       id="filter4169-3-5-8"
>> +       x="-0.031597666"
>> +       width="1.0631953"
>> +       y="-0.099812768"
>> +       height="1.1996255">
>> +      <feGaussianBlur
>> +         inkscape:collect="always"
>> +         stdDeviation="1.3307599"
>> +         id="feGaussianBlur4171-6-3-9" />
>> +    </filter>
>> +    <linearGradient
>> +       inkscape:collect="always"
>> +       xlink:href="#linearGradient5026"
>> +       id="linearGradient5032-3-8-2"
>> +       x1="353"
>> +       y1="211.3622"
>> +       x2="565.5"
>> +       y2="174.8622"
>> +       gradientUnits="userSpaceOnUse"
>> +       gradientTransform="matrix(2.1450559,0,0,1.0052679,-521.97704,740.76422)" />
>> +    <filter
>> +       inkscape:collect="always"
>> +       style="color-interpolation-filters:sRGB"
>> +       id="filter4169-3-5-8-5"
>> +       x="-0.031597666"
>> +       width="1.0631953"
>> +       y="-0.099812768"
>> +       height="1.1996255">
>> +      <feGaussianBlur
>> +         inkscape:collect="always"
>> +         stdDeviation="1.3307599"
>> +         id="feGaussianBlur4171-6-3-9-1" />
>> +    </filter>
>> +    <linearGradient
>> +       inkscape:collect="always"
>> +       xlink:href="#linearGradient5026"
>> +       id="linearGradient5032-3-8-0"
>> +       x1="353"
>> +       y1="211.3622"
>> +       x2="565.5"
>> +       y2="174.8622"
>> +       gradientUnits="userSpaceOnUse"
>> +       gradientTransform="matrix(1.0104674,0,0,1.0052679,83.456748,660.20747)" />
>> +    <filter
>> +       inkscape:collect="always"
>> +       style="color-interpolation-filters:sRGB"
>> +       id="filter4169-3-5-8-6"
>> +       x="-0.031597666"
>> +       width="1.0631953"
>> +       y="-0.099812768"
>> +       height="1.1996255">
>> +      <feGaussianBlur
>> +         inkscape:collect="always"
>> +         stdDeviation="1.3307599"
>> +         id="feGaussianBlur4171-6-3-9-2" />
>> +    </filter>
>> +    <linearGradient
>> +       inkscape:collect="always"
>> +       xlink:href="#linearGradient5026"
>> +       id="linearGradient5032-3-84"
>> +       x1="353"
>> +       y1="211.3622"
>> +       x2="565.5"
>> +       y2="174.8622"
>> +       gradientUnits="userSpaceOnUse"
>> +       gradientTransform="matrix(1.9884948,0,0,0.94903536,-318.42665,564.37696)" />
>> +    <filter
>> +       inkscape:collect="always"
>> +       style="color-interpolation-filters:sRGB"
>> +       id="filter4169-3-5-4"
>> +       x="-0.031597666"
>> +       width="1.0631953"
>> +       y="-0.099812768"
>> +       height="1.1996255">
>> +      <feGaussianBlur
>> +         inkscape:collect="always"
>> +         stdDeviation="1.3307599"
>> +         id="feGaussianBlur4171-6-3-0" />
>> +    </filter>
>> +    <marker
>> +       markerWidth="11.227358"
>> +       markerHeight="12.355258"
>> +       refX="10"
>> +       refY="6.177629"
>> +       orient="auto"
>> +       id="marker4825-6-0-0">
>> +      <path
>> +         inkscape:connector-curvature="0"
>> +         id="path4757-1-93-8"
>> +         d="M 0.42024733,0.42806444 10.231357,6.3500844 0.24347733,11.918544"
>> +         style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
>> +    </marker>
>> +    <marker
>> +       markerWidth="11.227358"
>> +       markerHeight="12.355258"
>> +       refX="10"
>> +       refY="6.177629"
>> +       orient="auto"
>> +       id="marker4825-6-3">
>> +      <path
>> +         inkscape:connector-curvature="0"
>> +         id="path4757-1-1"
>> +         d="M 0.42024733,0.42806444 10.231357,6.3500844 0.24347733,11.918544"
>> +         style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
>> +    </marker>
>> +  </defs>
>> +  <sodipodi:namedview
>> +     id="base"
>> +     pagecolor="#ffffff"
>> +     bordercolor="#666666"
>> +     borderopacity="1.0"
>> +     inkscape:pageopacity="0.0"
>> +     inkscape:pageshadow="2"
>> +     inkscape:zoom="0.98994949"
>> +     inkscape:cx="457.47339"
>> +     inkscape:cy="250.14781"
>> +     inkscape:document-units="px"
>> +     inkscape:current-layer="layer1"
>> +     showgrid="false"
>> +     inkscape:window-width="1916"
>> +     inkscape:window-height="1033"
>> +     inkscape:window-x="0"
>> +     inkscape:window-y="22"
>> +     inkscape:window-maximized="0"
>> +     fit-margin-right="0.3" />
>> +  <metadata
>> +     id="metadata7">
>> +    <rdf:RDF>
>> +      <cc:Work
>> +         rdf:about="">
>> +        <dc:format>image/svg+xml</dc:format>
>> +        <dc:type
>> +           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
>> +        <dc:title></dc:title>
>> +      </cc:Work>
>> +    </rdf:RDF>
>> +  </metadata>
>> +  <g
>> +     inkscape:label="Layer 1"
>> +     inkscape:groupmode="layer"
>> +     id="layer1"
>> +     transform="translate(0,-641.33861)">
>> +    <rect
>> +       style="fill:#000000;stroke:#000000;stroke-width:0.6465112;filter:url(#filter4169-3-5)"
>> +       id="rect4136-3-6-5"
>> +       width="101.07784"
>> +       height="31.998148"
>> +       x="128.74678"
>> +       y="80.648842"
>> +       transform="matrix(2.7384116,0,0,0.91666328,-284.06895,664.79751)" />
>> +    <rect
>> +       style="fill:url(#linearGradient5032-3);fill-opacity:1;stroke:#000000;stroke-width:1.02430749"
>> +       id="rect4136-2-6"
>> +       width="276.79272"
>> +       height="29.331528"
>> +       x="64.723419"
>> +       y="736.84473" />
>> +    <text
>> +       xml:space="preserve"
>> +       style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
>> +       x="78.223282"
>> +       y="756.79803"
>> +       id="text4138-6-2"><tspan
>> +         sodipodi:role="line"
>> +         id="tspan4140-1-9"
>> +         x="78.223282"
>> +         y="756.79803"
>> +         style="font-size:15px;line-height:1.25">user application (running by the CPU</tspan></text>
>> +    <path
>> +       style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker4825-6)"
>> +       d="m 217.67507,876.6738 113.40331,45.0758"
>> +       id="path4661"
>> +       inkscape:connector-curvature="0"
>> +       sodipodi:nodetypes="cc" />
>> +    <path
>> +       style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker4825-6-0)"
>> +       d="m 208.10197,767.69811 0.29362,76.03656"
>> +       id="path4661-6"
>> +       inkscape:connector-curvature="0"
>> +       sodipodi:nodetypes="cc" />
>> +    <rect
>> +       style="fill:#000000;stroke:#000000;stroke-width:0.6465112;filter:url(#filter4169-3-5-8)"
>> +       id="rect4136-3-6-5-3"
>> +       width="101.07784"
>> +       height="31.998148"
>> +       x="128.74678"
>> +       y="80.648842"
>> +       transform="matrix(1.0104673,0,0,1.0052679,28.128628,763.90722)" />
>> +    <rect
>> +       style="fill:url(#linearGradient5032-3-8);fill-opacity:1;stroke:#000000;stroke-width:0.65159565"
>> +       id="rect4136-2-6-6"
>> +       width="102.13586"
>> +       height="32.16671"
>> +       x="156.83217"
>> +       y="842.91852" />
>> +    <text
>> +       xml:space="preserve"
>> +       style="font-style:normal;font-weight:normal;font-size:12px;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
>> +       x="188.58519"
>> +       y="864.47125"
>> +       id="text4138-6-2-8"><tspan
>> +         sodipodi:role="line"
>> +         id="tspan4140-1-9-0"
>> +         x="188.58519"
>> +         y="864.47125"
>> +         style="font-size:15px;line-height:1.25;stroke-width:1px">MMU</tspan></text>
>> +    <rect
>> +       style="fill:#000000;stroke:#000000;stroke-width:0.6465112;filter:url(#filter4169-3-5-8-5)"
>> +       id="rect4136-3-6-5-3-1"
>> +       width="101.07784"
>> +       height="31.998148"
>> +       x="128.74678"
>> +       y="80.648842"
>> +       transform="matrix(2.1450556,0,0,1.0052679,1.87637,843.51696)" />
>> +    <rect
>> +       style="fill:url(#linearGradient5032-3-8-2);fill-opacity:1;stroke:#000000;stroke-width:0.94937181"
>> +       id="rect4136-2-6-6-0"
>> +       width="216.8176"
>> +       height="32.16671"
>> +       x="275.09283"
>> +       y="922.5282" />
>> +    <text
>> +       xml:space="preserve"
>> +       style="font-style:normal;font-weight:normal;font-size:12px;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
>> +       x="347.81482"
>> +       y="943.23291"
>> +       id="text4138-6-2-8-8"><tspan
>> +         sodipodi:role="line"
>> +         id="tspan4140-1-9-0-5"
>> +         x="347.81482"
>> +         y="943.23291"
>> +         style="font-size:15px;line-height:1.25;stroke-width:1px">Memory</tspan></text>
>> +    <rect
>> +       style="fill:#000000;stroke:#000000;stroke-width:0.6465112;filter:url(#filter4169-3-5-8-6)"
>> +       id="rect4136-3-6-5-3-5"
>> +       width="101.07784"
>> +       height="31.998148"
>> +       x="128.74678"
>> +       y="80.648842"
>> +       transform="matrix(1.0104673,0,0,1.0052679,330.22737,762.9602)" />
>> +    <rect
>> +       style="fill:url(#linearGradient5032-3-8-0);fill-opacity:1;stroke:#000000;stroke-width:0.65159565"
>> +       id="rect4136-2-6-6-8"
>> +       width="102.13586"
>> +       height="32.16671"
>> +       x="458.93091"
>> +       y="841.9715" />
>> +    <text
>> +       xml:space="preserve"
>> +       style="font-style:normal;font-weight:normal;font-size:12px;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
>> +       x="490.68393"
>> +       y="863.52423"
>> +       id="text4138-6-2-8-6"><tspan
>> +         sodipodi:role="line"
>> +         id="tspan4140-1-9-0-2"
>> +         x="490.68393"
>> +         y="863.52423"
>> +         style="font-size:15px;line-height:1.25;stroke-width:1px">IOMMU</tspan></text>
>> +    <rect
>> +       style="fill:#000000;stroke:#000000;stroke-width:0.6465112;filter:url(#filter4169-3-5-4)"
>> +       id="rect4136-3-6-5-6"
>> +       width="101.07784"
>> +       height="31.998148"
>> +       x="128.74678"
>> +       y="80.648842"
>> +       transform="matrix(1.9884947,0,0,0.94903537,167.19229,661.38193)" />
>> +    <rect
>> +       style="fill:url(#linearGradient5032-3-84);fill-opacity:1;stroke:#000000;stroke-width:0.88813609"
>> +       id="rect4136-2-6-2"
>> +       width="200.99274"
>> +       height="30.367374"
>> +       x="420.4675"
>> +       y="735.97351" />
>> +    <text
>> +       xml:space="preserve"
>> +       style="font-style:normal;font-weight:normal;font-size:12px;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
>> +       x="441.95297"
>> +       y="755.9068"
>> +       id="text4138-6-2-9"><tspan
>> +         sodipodi:role="line"
>> +         id="tspan4140-1-9-9"
>> +         x="441.95297"
>> +         y="755.9068"
>> +         style="font-size:15px;line-height:1.25;stroke-width:1px">Hardware Accelerator</tspan></text>
>> +    <path
>> +       style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker4825-6-0-0)"
>> +       d="m 508.2914,766.55885 0.29362,76.03656"
>> +       id="path4661-6-1"
>> +       inkscape:connector-curvature="0"
>> +       sodipodi:nodetypes="cc" />
>> +    <path
>> +       style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker4825-6-3)"
>> +       d="M 499.70201,876.47297 361.38296,920.80258"
>> +       id="path4661-1"
>> +       inkscape:connector-curvature="0"
>> +       sodipodi:nodetypes="cc" />
>> +  </g>
>> +</svg>
>> diff --git a/Documentation/warpdrive/wd_q_addr_space.svg b/Documentation/warpdrive/wd_q_addr_space.svg
>> new file mode 100644
>> index 000000000000..5e6cf8e89908
>> --- /dev/null
>> +++ b/Documentation/warpdrive/wd_q_addr_space.svg
>> @@ -0,0 +1,359 @@
>> +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
>> +<!-- Created with Inkscape (http://www.inkscape.org/) -->
>> +
>> +<svg
>> +   xmlns:dc="http://purl.org/dc/elements/1.1/"
>> +   xmlns:cc="http://creativecommons.org/ns#"
>> +   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
>> +   xmlns:svg="http://www.w3.org/2000/svg"
>> +   xmlns="http://www.w3.org/2000/svg"
>> +   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
>> +   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
>> +   width="210mm"
>> +   height="124mm"
>> +   viewBox="0 0 210 124"
>> +   version="1.1"
>> +   id="svg8"
>> +   inkscape:version="0.92.3 (2405546, 2018-03-11)"
>> +   sodipodi:docname="wd_q_addr_space.svg">
>> +  <defs
>> +     id="defs2">
>> +    <marker
>> +       inkscape:stockid="Arrow1Mend"
>> +       orient="auto"
>> +       refY="0"
>> +       refX="0"
>> +       id="marker5428"
>> +       style="overflow:visible"
>> +       inkscape:isstock="true">
>> +      <path
>> +         id="path5426"
>> +         d="M 0,0 5,-5 -12.5,0 5,5 Z"
>> +         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
>> +         transform="matrix(-0.4,0,0,-0.4,-4,0)"
>> +         inkscape:connector-curvature="0" />
>> +    </marker>
>> +    <marker
>> +       inkscape:isstock="true"
>> +       style="overflow:visible"
>> +       id="marker2922"
>> +       refX="0"
>> +       refY="0"
>> +       orient="auto"
>> +       inkscape:stockid="Arrow1Mend"
>> +       inkscape:collect="always">
>> +      <path
>> +         transform="matrix(-0.4,0,0,-0.4,-4,0)"
>> +         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
>> +         d="M 0,0 5,-5 -12.5,0 5,5 Z"
>> +         id="path2920"
>> +         inkscape:connector-curvature="0" />
>> +    </marker>
>> +    <marker
>> +       inkscape:stockid="Arrow1Mstart"
>> +       orient="auto"
>> +       refY="0"
>> +       refX="0"
>> +       id="Arrow1Mstart"
>> +       style="overflow:visible"
>> +       inkscape:isstock="true">
>> +      <path
>> +         id="path840"
>> +         d="M 0,0 5,-5 -12.5,0 5,5 Z"
>> +         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
>> +         transform="matrix(0.4,0,0,0.4,4,0)"
>> +         inkscape:connector-curvature="0" />
>> +    </marker>
>> +    <marker
>> +       inkscape:stockid="Arrow1Mend"
>> +       orient="auto"
>> +       refY="0"
>> +       refX="0"
>> +       id="Arrow1Mend"
>> +       style="overflow:visible"
>> +       inkscape:isstock="true"
>> +       inkscape:collect="always">
>> +      <path
>> +         id="path843"
>> +         d="M 0,0 5,-5 -12.5,0 5,5 Z"
>> +         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
>> +         transform="matrix(-0.4,0,0,-0.4,-4,0)"
>> +         inkscape:connector-curvature="0" />
>> +    </marker>
>> +    <marker
>> +       inkscape:stockid="Arrow1Mstart"
>> +       orient="auto"
>> +       refY="0"
>> +       refX="0"
>> +       id="Arrow1Mstart-5"
>> +       style="overflow:visible"
>> +       inkscape:isstock="true">
>> +      <path
>> +         inkscape:connector-curvature="0"
>> +         id="path840-1"
>> +         d="M 0,0 5,-5 -12.5,0 5,5 Z"
>> +         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
>> +         transform="matrix(0.4,0,0,0.4,4,0)" />
>> +    </marker>
>> +    <marker
>> +       inkscape:stockid="Arrow1Mend"
>> +       orient="auto"
>> +       refY="0"
>> +       refX="0"
>> +       id="Arrow1Mend-1"
>> +       style="overflow:visible"
>> +       inkscape:isstock="true">
>> +      <path
>> +         inkscape:connector-curvature="0"
>> +         id="path843-0"
>> +         d="M 0,0 5,-5 -12.5,0 5,5 Z"
>> +         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
>> +         transform="matrix(-0.4,0,0,-0.4,-4,0)" />
>> +    </marker>
>> +    <marker
>> +       inkscape:isstock="true"
>> +       style="overflow:visible"
>> +       id="marker2922-2"
>> +       refX="0"
>> +       refY="0"
>> +       orient="auto"
>> +       inkscape:stockid="Arrow1Mend"
>> +       inkscape:collect="always">
>> +      <path
>> +         transform="matrix(-0.4,0,0,-0.4,-4,0)"
>> +         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
>> +         d="M 0,0 5,-5 -12.5,0 5,5 Z"
>> +         id="path2920-9"
>> +         inkscape:connector-curvature="0" />
>> +    </marker>
>> +    <marker
>> +       inkscape:isstock="true"
>> +       style="overflow:visible"
>> +       id="marker2922-27"
>> +       refX="0"
>> +       refY="0"
>> +       orient="auto"
>> +       inkscape:stockid="Arrow1Mend"
>> +       inkscape:collect="always">
>> +      <path
>> +         transform="matrix(-0.4,0,0,-0.4,-4,0)"
>> +         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
>> +         d="M 0,0 5,-5 -12.5,0 5,5 Z"
>> +         id="path2920-0"
>> +         inkscape:connector-curvature="0" />
>> +    </marker>
>> +    <marker
>> +       inkscape:isstock="true"
>> +       style="overflow:visible"
>> +       id="marker2922-27-8"
>> +       refX="0"
>> +       refY="0"
>> +       orient="auto"
>> +       inkscape:stockid="Arrow1Mend"
>> +       inkscape:collect="always">
>> +      <path
>> +         transform="matrix(-0.4,0,0,-0.4,-4,0)"
>> +         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
>> +         d="M 0,0 5,-5 -12.5,0 5,5 Z"
>> +         id="path2920-0-0"
>> +         inkscape:connector-curvature="0" />
>> +    </marker>
>> +  </defs>
>> +  <sodipodi:namedview
>> +     id="base"
>> +     pagecolor="#ffffff"
>> +     bordercolor="#666666"
>> +     borderopacity="1.0"
>> +     inkscape:pageopacity="0.0"
>> +     inkscape:pageshadow="2"
>> +     inkscape:zoom="1.4"
>> +     inkscape:cx="401.66654"
>> +     inkscape:cy="218.12255"
>> +     inkscape:document-units="mm"
>> +     inkscape:current-layer="layer1"
>> +     showgrid="false"
>> +     inkscape:window-width="1916"
>> +     inkscape:window-height="1033"
>> +     inkscape:window-x="0"
>> +     inkscape:window-y="22"
>> +     inkscape:window-maximized="0" />
>> +  <metadata
>> +     id="metadata5">
>> +    <rdf:RDF>
>> +      <cc:Work
>> +         rdf:about="">
>> +        <dc:format>image/svg+xml</dc:format>
>> +        <dc:type
>> +           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
>> +        <dc:title />
>> +      </cc:Work>
>> +    </rdf:RDF>
>> +  </metadata>
>> +  <g
>> +     inkscape:label="Layer 1"
>> +     inkscape:groupmode="layer"
>> +     id="layer1"
>> +     transform="translate(0,-173)">
>> +    <rect
>> +       style="opacity:0.82999998;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.4;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.82745098"
>> +       id="rect815"
>> +       width="21.262758"
>> +       height="40.350552"
>> +       x="55.509361"
>> +       y="195.00098"
>> +       ry="0" />
>> +    <rect
>> +       style="opacity:0.82999998;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.4;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.82745098"
>> +       id="rect815-1"
>> +       width="21.24276"
>> +       height="43.732346"
>> +       x="55.519352"
>> +       y="235.26543"
>> +       ry="0" />
>> +    <text
>> +       xml:space="preserve"
>> +       style="font-style:normal;font-weight:normal;font-size:2.9765625px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
>> +       x="50.549229"
>> +       y="190.6078"
>> +       id="text1118"><tspan
>> +         sodipodi:role="line"
>> +         id="tspan1116"
>> +         x="50.549229"
>> +         y="190.6078"
>> +         style="stroke-width:0.26458332px">queue file address space</tspan></text>
>> +    <path
>> +       style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
>> +       d="M 76.818568,194.95453 H 97.229281"
>> +       id="path1126"
>> +       inkscape:connector-curvature="0"
>> +       sodipodi:nodetypes="cc" />
>> +    <path
>> +       style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
>> +       d="M 76.818568,235.20899 H 96.095361"
>> +       id="path1126-8"
>> +       inkscape:connector-curvature="0" />
>> +    <path
>> +       style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
>> +       d="m 76.762111,278.99778 h 19.27678"
>> +       id="path1126-0"
>> +       inkscape:connector-curvature="0" />
>> +    <path
>> +       style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
>> +       d="m 55.519355,265.20165 v 19.27678"
>> +       id="path1126-2"
>> +       inkscape:connector-curvature="0" />
>> +    <path
>> +       style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
>> +       d="m 76.762111,265.20165 v 19.27678"
>> +       id="path1126-2-1"
>> +       inkscape:connector-curvature="0" />
>> +    <path
>> +       style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#Arrow1Mstart);marker-end:url(#Arrow1Mend)"
>> +       d="m 87.590896,194.76554 0,39.87648"
>> +       id="path1126-2-1-0"
>> +       inkscape:connector-curvature="0"
>> +       sodipodi:nodetypes="cc" />
>> +    <path
>> +       style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#Arrow1Mstart-5);marker-end:url(#Arrow1Mend-1)"
>> +       d="m 82.48822,235.77596 v 42.90029"
>> +       id="path1126-2-1-0-8"
>> +       inkscape:connector-curvature="0"
>> +       sodipodi:nodetypes="cc" />
>> +    <path
>> +       style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker2922)"
>> +       d="M 44.123633,195.3325 H 55.651907"
>> +       id="path2912"
>> +       inkscape:connector-curvature="0" />
>> +    <text
>> +       xml:space="preserve"
>> +       style="font-style:normal;font-weight:normal;font-size:2.9765625px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
>> +       x="32.217381"
>> +       y="196.27745"
>> +       id="text2968"><tspan
>> +         sodipodi:role="line"
>> +         id="tspan2966"
>> +         x="32.217381"
>> +         y="196.27745"
>> +         style="stroke-width:0.26458332px">offset 0</tspan></text>
>> +    <text
>> +       xml:space="preserve"
>> +       style="font-style:normal;font-weight:normal;font-size:2.9765625px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
>> +       x="91.199554"
>> +       y="216.03946"
>> +       id="text1118-5"><tspan
>> +         sodipodi:role="line"
>> +         id="tspan1116-0"
>> +         x="91.199554"
>> +         y="216.03946"
>> +         style="stroke-width:0.26458332px">device region (mapped to device mmio or shared kernel driver memory)</tspan></text>
>> +    <text
>> +       xml:space="preserve"
>> +       style="font-style:normal;font-weight:normal;font-size:2.9765625px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
>> +       x="86.188072"
>> +       y="244.50081"
>> +       id="text1118-5-6"><tspan
>> +         sodipodi:role="line"
>> +         id="tspan1116-0-4"
>> +         x="86.188072"
>> +         y="244.50081"
>> +         style="stroke-width:0.26458332px">static share virtual memory region (for device without share virtual memory)</tspan></text>
>> +    <flowRoot
>> +       xml:space="preserve"
>> +       id="flowRoot5699"
>> +       style="font-style:normal;font-weight:normal;font-size:11.25px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"><flowRegion
>> +         id="flowRegion5701"><rect
>> +           id="rect5703"
>> +           width="5182.8569"
>> +           height="385.71429"
>> +           x="34.285713"
>> +           y="71.09111" /></flowRegion><flowPara
>> +         id="flowPara5705" /></flowRoot>    <path
>> +       style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker2922-2)"
>> +       d="M 43.679028,206.85268 H 55.207302"
>> +       id="path2912-1"
>> +       inkscape:connector-curvature="0" />
>> +    <path
>> +       style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker2922-27)"
>> +       d="M 44.057004,224.23959 H 55.585278"
>> +       id="path2912-9"
>> +       inkscape:connector-curvature="0" />
>> +    <text
>> +       xml:space="preserve"
>> +       style="font-style:normal;font-weight:normal;font-size:2.9765625px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
>> +       x="24.139778"
>> +       y="202.40636"
>> +       id="text1118-5-3"><tspan
>> +         sodipodi:role="line"
>> +         id="tspan1116-0-6"
>> +         x="24.139778"
>> +         y="202.40636"
>> +         style="stroke-width:0.26458332px">device mmio region</tspan></text>
>> +    <text
>> +       xml:space="preserve"
>> +       style="font-style:normal;font-weight:normal;font-size:2.9765625px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
>> +       x="17.010948"
>> +       y="216.73672"
>> +       id="text1118-5-3-3"><tspan
>> +         sodipodi:role="line"
>> +         id="tspan1116-0-6-6"
>> +         x="17.010948"
>> +         y="216.73672"
>> +         style="stroke-width:0.26458332px">device kernel only  region</tspan></text>
>> +    <path
>> +       style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker2922-27-8)"
>> +       d="M 43.981087,235.35153 H 55.509361"
>> +       id="path2912-9-2"
>> +       inkscape:connector-curvature="0" />
>> +    <text
>> +       xml:space="preserve"
>> +       style="font-style:normal;font-weight:normal;font-size:2.9765625px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
>> +       x="17.575975"
>> +       y="230.53285"
>> +       id="text1118-5-3-3-0"><tspan
>> +         sodipodi:role="line"
>> +         id="tspan1116-0-6-6-5"
>> +         x="17.575975"
>> +         y="230.53285"
>> +         style="stroke-width:0.26458332px">device user share  region</tspan></text>
>> +  </g>
>> +</svg>
>> --
>> 2.17.1
>>

^ permalink raw reply

* Re: [PATCHv2 net-next 1/4] sctp: define subscribe in sctp_sock as __u16
From: Neil Horman @ 2018-11-13 17:15 UTC (permalink / raw)
  To: Xin Long; +Cc: network dev, linux-sctp, Marcelo Ricardo Leitner, davem
In-Reply-To: <82150b4fab9e70377db3db9c62fd10323be3f294.1542089666.git.lucien.xin@gmail.com>

On Tue, Nov 13, 2018 at 02:24:53PM +0800, Xin Long wrote:
>  
>  	/* Default Peer Address Parameters.  These defaults can
>  	 * be modified via SCTP_PEER_ADDR_PARAMS
> @@ -5267,14 +5274,24 @@ static int sctp_getsockopt_disable_fragments(struct sock *sk, int len,
>  static int sctp_getsockopt_events(struct sock *sk, int len, char __user *optval,
>  				  int __user *optlen)
>  {
> +	struct sctp_event_subscribe subscribe;
> +	__u8 *sn_type = (__u8 *)&subscribe;
> +	int i;
> +
>  	if (len == 0)
>  		return -EINVAL;
>  	if (len > sizeof(struct sctp_event_subscribe))
>  		len = sizeof(struct sctp_event_subscribe);
>  	if (put_user(len, optlen))
>  		return -EFAULT;
> -	if (copy_to_user(optval, &sctp_sk(sk)->subscribe, len))
> +
> +	for (i = 0; i <= len; i++)
> +		sn_type[i] = sctp_ulpevent_type_enabled(sctp_sk(sk)->subscribe,
> +							SCTP_SN_TYPE_BASE + i);
> +
This seems like an off by one error.  sctp_event_subscribe has N bytes in it (1
byte for each event), meaning that that events 0-(N-1) are subscribable.
Iterating this loop imples that you are going to check N events, overrunning the
sctp_event_subscribe struct.

Neil

> 

^ permalink raw reply

* [PATCH net] ipvs: call ip_vs_dst_notifier before ipv6_dev_notf
From: Xin Long @ 2018-11-13 17:25 UTC (permalink / raw)
  To: network dev, netfilter-devel; +Cc: davem, pablo, Hans Schillstrom

ip_vs_dst_event is supposed to clean up all dst used in ipvs'
destinations when a net dev is going down. But it works only
when the dst's dev is the same as the dev from the event.

Now with the same priority but late registration,
ip_vs_dst_notifier is always called after ipv6_dev_notf where
the dst's dev is set to lo for NETDEV_DOWN event.

As the dst's dev lo is not the same as the dev from the event
in ip_vs_dst_event(), ipv6_dev_notf can actually never work.
Also as these dst have to wait for dest_trash_timer to clean
them up. It would cause some non-permanent kernel warnings:

  unregister_netdevice: waiting for br0 to become free. Usage count = 3

To fix it, call ip_vs_dst_notifier before ipv6_dev_notf by
increasing its priority to ADDRCONF_NOTIFY_PRIORITY + 5.

Fixes: 7a4f0761fce3 ("IPVS: init and cleanup restructuring")
Reported-by: Li Shuang <shuali@redhat.com>
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
 net/netfilter/ipvs/ip_vs_ctl.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index 83395bf6..aded477 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -3980,6 +3980,7 @@ static void __net_exit ip_vs_control_net_cleanup_sysctl(struct netns_ipvs *ipvs)
 
 static struct notifier_block ip_vs_dst_notifier = {
 	.notifier_call = ip_vs_dst_event,
+	.priority = ADDRCONF_NOTIFY_PRIORITY + 5,
 };
 
 int __net_init ip_vs_control_net_init(struct netns_ipvs *ipvs)
-- 
2.1.0

^ permalink raw reply related

* Re: BUG: sleeping function called from invalid context at mm/slab.h:421
From: Roman Gushchin @ 2018-11-13 17:36 UTC (permalink / raw)
  To: Naresh Kamboju
  Cc: netdev@vger.kernel.org, ast@kernel.org, Daniel Borkmann,
	Martin Lau
In-Reply-To: <CA+G9fYsp4UrrY9t5VZDSQn20SFxePTghsHPa3hOyZ7exvfrmHw@mail.gmail.com>

On Tue, Nov 13, 2018 at 10:03:38PM +0530, Naresh Kamboju wrote:
> While running kernel selftests bpf test_cgroup_storage test this
> kernel BUG reported every time on all devices running Linux -next
> 4.20.0-rc2-next-20181113 (from 4.19.0-rc5-next-20180928).
> This kernel BUG log is from x86_64 machine.
> 
> Do you see at your end ?
> 
> [   73.047526] BUG: sleeping function called from invalid context at
> /srv/oe/build/tmp-rpb-glibc/work-shared/intel-corei7-64/kernel-source/mm/slab.h:421
> [   73.060915] in_atomic(): 1, irqs_disabled(): 0, pid: 3157, name:
> test_cgroup_sto
> [   73.068342] INFO: lockdep is turned off.
> [   73.072293] CPU: 2 PID: 3157 Comm: test_cgroup_sto Not tainted
> 4.20.0-rc2-next-20181113 #1
> [   73.080548] Hardware name: Supermicro SYS-5019S-ML/X11SSH-F, BIOS
> 2.0b 07/27/2017
> [   73.088018] Call Trace:
> [   73.090463]  dump_stack+0x70/0xa5
> [   73.093783]  ___might_sleep+0x152/0x240
> [   73.097619]  __might_sleep+0x4a/0x80
> [   73.101191]  __kmalloc_node+0x1cf/0x2f0
> [   73.105031]  ? cgroup_storage_update_elem+0x46/0x90
> [   73.109909]  cgroup_storage_update_elem+0x46/0x90
> [   73.114608]  map_update_elem+0x4a1/0x4c0
> [   73.118534]  __x64_sys_bpf+0x124/0x280
> [   73.122286]  do_syscall_64+0x4f/0x190
> [   73.125952]  entry_SYSCALL_64_after_hwframe+0x49/0xbe
> [   73.131004] RIP: 0033:0x7f46b93ea7f9
> [   73.134581] Code: 00 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00
> 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24
> 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 4f e6 2b 00 f7 d8 64 89
> 01 48
> [   73.153318] RSP: 002b:00007fffc6595858 EFLAGS: 00000206 ORIG_RAX:
> 0000000000000141
> [   73.160876] RAX: ffffffffffffffda RBX: 00000000014a0260 RCX: 00007f46b93ea7f9
> [   73.167999] RDX: 0000000000000048 RSI: 00007fffc65958a0 RDI: 0000000000000002
> [   73.175124] RBP: 00007fffc6595870 R08: 00007fffc65958a0 R09: 00007fffc65958a0
> [   73.182246] R10: 00007fffc65958a0 R11: 0000000000000206 R12: 0000000000000003
> [   73.189369] R13: 0000000000000004 R14: 0000000000000005 R15: 0000000000000006
> selftests: bpf: test_cgroup_storage

Hi Naresh!

Thank you for the report! Can you, please, try the following patch?

Thanks!

^ permalink raw reply

* Re: [Patch net-next v2] net: dump more useful information in netdev_rx_csum_fault()
From: Willem de Bruijn @ 2018-11-13 18:00 UTC (permalink / raw)
  To: Cong Wang; +Cc: Network Development
In-Reply-To: <20181112224718.19496-1-xiyou.wangcong@gmail.com>

On Mon, Nov 12, 2018 at 2:49 PM Cong Wang <xiyou.wangcong@gmail.com> wrote:
>
> Currently netdev_rx_csum_fault() only shows a device name,
> we need more information about the skb for debugging csum
> failures.
>
> Sample output:
>
>  ens3: hw csum failure
>  dev features: 0x0000000000014b89
>  skb len=84 data_len=0 pkt_type=0 gso_size=0 gso_type=0 nr_frags=0 ip_summed=0 csum=0 csum_complete_sw=0 csum_valid=0 csum_level=0

Recent issues were protocol dependent, including whether vlan headers
were present. Perhaps also print skb vlan fields and even the first N
bytes of data to inspect protocol headers? Also skb_iif, esp. if this
differs from dev->ifindex.

^ permalink raw reply

* Re: [Patch net-next v2] net: dump more useful information in netdev_rx_csum_fault()
From: Cong Wang @ 2018-11-13 18:14 UTC (permalink / raw)
  To: Willem de Bruijn; +Cc: Linux Kernel Network Developers
In-Reply-To: <CAF=yD-KWt2NV5hrDrG09yCHb9jQs8oxm5iQAyEhw7GqFZ4a9eg@mail.gmail.com>

On Tue, Nov 13, 2018 at 10:01 AM Willem de Bruijn
<willemdebruijn.kernel@gmail.com> wrote:
>
> On Mon, Nov 12, 2018 at 2:49 PM Cong Wang <xiyou.wangcong@gmail.com> wrote:
> >
> > Currently netdev_rx_csum_fault() only shows a device name,
> > we need more information about the skb for debugging csum
> > failures.
> >
> > Sample output:
> >
> >  ens3: hw csum failure
> >  dev features: 0x0000000000014b89
> >  skb len=84 data_len=0 pkt_type=0 gso_size=0 gso_type=0 nr_frags=0 ip_summed=0 csum=0 csum_complete_sw=0 csum_valid=0 csum_level=0
>
> Recent issues were protocol dependent, including whether vlan headers
> were present. Perhaps also print skb vlan fields and even the first N
> bytes of data to inspect protocol headers? Also skb_iif, esp. if this
> differs from dev->ifindex.

Pawel's case seems to be vlan related, however, as I mentioned,
my case is neither vlan nor RXFCS related.

Ideally, we should dump the whole packet in order to verify the
correctness of the checksum. :) It is not easy to do so given
how complex an skb is now. This is why I only select a few skb
fields to dump. I am pretty sure this can't cover all cases, you
can always add more for your need in the future.

Thanks.

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox