[PATCH v9 1/8] thunderbolt: Macro rename

2016-11-09 Thread Amir Levy
This first patch updates the NHI Thunderbolt controller registers file to
reflect that it is not only for Cactus Ridge.
No functional change intended.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
Signed-off-by: Andreas Noever <andreas.noe...@gmail.com>
---
 drivers/thunderbolt/nhi_regs.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/thunderbolt/nhi_regs.h b/drivers/thunderbolt/nhi_regs.h
index 86b996c..75cf069 100644
--- a/drivers/thunderbolt/nhi_regs.h
+++ b/drivers/thunderbolt/nhi_regs.h
@@ -1,11 +1,11 @@
 /*
- * Thunderbolt Cactus Ridge driver - NHI registers
+ * Thunderbolt driver - NHI registers
  *
  * Copyright (c) 2014 Andreas Noever <andreas.noe...@gmail.com>
  */
 
-#ifndef DSL3510_REGS_H_
-#define DSL3510_REGS_H_
+#ifndef NHI_REGS_H_
+#define NHI_REGS_H_
 
 #include 
 
-- 
2.7.4



[PATCH v9 4/8] thunderbolt: Networking state machine

2016-11-09 Thread Amir Levy
This patch builds the peer to peer communication path.
Communication is established by a negotiation process whereby messages are
sent back and forth between the peers until a connection is established.
This includes the Thunderbolt Network driver communication with the second
peer via Intel Connection Manager(ICM) firmware.
  ++++
  |Host 1  ||Host 2  |
  ||||
  | +---+  || +---+  |
  | |Thunderbolt|  || |Thunderbolt|  |
  | |Networking |  || |Networking |  |
  | |Driver |  || |Driver |  |
  | +---+  || +---+  |
  |  ^ ||  ^ |
  |  | ||  | |
  | ++---+ || ++---+ |
  | |Thunderbolt |   | || |Thunderbolt |   | |
  | |Controller  v   | || |Controller  v   | |
  | | +---+  | || | +---+  | |
  | | |ICM|<-+-++-+>|ICM|  | |
  | | +---+  | || | +---+  | |
  | ++ || ++ |
  ++++
Note that this patch only establishes the link between the two hosts and
not Network Packet handling - this is dealt with in the next patch.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 drivers/thunderbolt/icm/Makefile  |   2 +-
 drivers/thunderbolt/icm/icm_nhi.c | 262 -
 drivers/thunderbolt/icm/net.c | 783 ++
 drivers/thunderbolt/icm/net.h |  70 
 4 files changed, 1109 insertions(+), 8 deletions(-)
 create mode 100644 drivers/thunderbolt/icm/net.c

diff --git a/drivers/thunderbolt/icm/Makefile b/drivers/thunderbolt/icm/Makefile
index f0d0fbb..94a2797 100644
--- a/drivers/thunderbolt/icm/Makefile
+++ b/drivers/thunderbolt/icm/Makefile
@@ -1,2 +1,2 @@
 obj-${CONFIG_THUNDERBOLT_ICM} += thunderbolt-icm.o
-thunderbolt-icm-objs := icm_nhi.o
+thunderbolt-icm-objs := icm_nhi.o net.o
diff --git a/drivers/thunderbolt/icm/icm_nhi.c 
b/drivers/thunderbolt/icm/icm_nhi.c
index c843ce8..edc910b 100644
--- a/drivers/thunderbolt/icm/icm_nhi.c
+++ b/drivers/thunderbolt/icm/icm_nhi.c
@@ -64,6 +64,13 @@ static const struct nla_policy nhi_genl_policy[NHI_ATTR_MAX 
+ 1] = {
.len = TBT_ICM_RING_MAX_FRAME_SIZE },
[NHI_ATTR_MSG_FROM_ICM] = { .type = NLA_BINARY,
.len = TBT_ICM_RING_MAX_FRAME_SIZE },
+   [NHI_ATTR_LOCAL_ROUTE_STRING]   = {
+   .len = sizeof(struct route_string) },
+   [NHI_ATTR_LOCAL_UUID]   = { .len = sizeof(uuid_be) },
+   [NHI_ATTR_REMOTE_UUID]  = { .len = sizeof(uuid_be) },
+   [NHI_ATTR_LOCAL_DEPTH]  = { .type = NLA_U8, },
+   [NHI_ATTR_ENABLE_FULL_E2E]  = { .type = NLA_FLAG, },
+   [NHI_ATTR_MATCH_FRAME_ID]   = { .type = NLA_FLAG, },
 };
 
 /* NHI genetlink family */
@@ -480,6 +487,29 @@ int nhi_mailbox(struct tbt_nhi_ctxt *nhi_ctxt, u32 cmd, 
u32 data, bool deinit)
return 0;
 }
 
+static inline bool nhi_is_path_disconnected(u32 cmd, u8 num_ports)
+{
+   return (cmd >= DISCONNECT_PORT_A_INTER_DOMAIN_PATH &&
+   cmd < (DISCONNECT_PORT_A_INTER_DOMAIN_PATH + num_ports));
+}
+
+static int nhi_mailbox_disconn_path(struct tbt_nhi_ctxt *nhi_ctxt, u32 cmd)
+   __releases(_list_mutex)
+{
+   struct port_net_dev *port;
+   u32 port_num = cmd - DISCONNECT_PORT_A_INTER_DOMAIN_PATH;
+
+   port = &(nhi_ctxt->net_devices[port_num]);
+   mutex_lock(>state_mutex);
+
+   mutex_unlock(_list_mutex);
+   port->medium_sts = MEDIUM_READY_FOR_APPROVAL;
+   if (port->net_dev)
+   negotiation_events(port->net_dev, MEDIUM_DISCONNECTED);
+   mutex_unlock(>state_mutex);
+   return  0;
+}
+
 static int nhi_mailbox_generic(struct tbt_nhi_ctxt *nhi_ctxt, u32 mb_cmd)
__releases(_list_mutex)
 {
@@ -526,13 +556,90 @@ static int nhi_genl_mailbox(__always_unused struct 
sk_buff *u_skb,
return -ERESTART;
 
nhi_ctxt = nhi_search_ctxt(*(u32 *)info->userhdr);
-   if (nhi_ctxt && !nhi_ctxt->d0_exit)
-   return nhi_mailbox_generic(nhi_ctxt, mb_cmd);
+   if (nhi_ctxt && !nhi_ctxt->d0_exit) {
+
+   /* rwsem is released later by the below functions */
+   if (nhi_is_path_disconnected(cmd, nhi_ctxt->num_ports))
+   return nhi_mailbox_disconn_path(nhi_ctxt, cmd);
+   else
+   return nhi_mailbox_generic(nhi_ctxt, mb_cmd);
+
+   }
 
mutex_unlock(_list_

[PATCH v9 6/8] thunderbolt: Kconfig for Thunderbolt Networking

2016-11-09 Thread Amir Levy
Update to the Kconfig Thunderbolt description to add
Thunderbolt networking as an option.
The menu item "Thunderbolt support" now offers:
"Apple Hardware Support" (existing)
and/or
"Thunderbolt Networking" (new)

You can choose the driver for your platform or build both drivers -
each driver will detect if it can run on the specific platform.
If the Thunderbolt Networking option is chosen, Thunderbolt Networking
will be enabled between Linux non-Apple systems, macOS and
Windows based systems.
Thunderbolt Networking will not affect any other Thunderbolt feature that
was previous available to Linux users on either Apple or
non-Apple platforms.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 drivers/thunderbolt/Kconfig  | 27 +++
 drivers/thunderbolt/Makefile |  3 ++-
 2 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/drivers/thunderbolt/Kconfig b/drivers/thunderbolt/Kconfig
index c121acc..376e5bb 100644
--- a/drivers/thunderbolt/Kconfig
+++ b/drivers/thunderbolt/Kconfig
@@ -1,13 +1,32 @@
-menuconfig THUNDERBOLT
-   tristate "Thunderbolt support for Apple devices"
+config THUNDERBOLT
+   tristate "Thunderbolt support"
depends on PCI
select CRC32
help
- Cactus Ridge Thunderbolt Controller driver
+ Thunderbolt Controller driver
+
+if THUNDERBOLT
+
+config THUNDERBOLT_APPLE
+   tristate "Apple hardware support"
+   help
  This driver is required if you want to hotplug Thunderbolt devices on
  Apple hardware.
 
  Device chaining is currently not supported.
 
- To compile this driver a module, choose M here. The module will be
+ To compile this driver as a module, choose M here. The module will be
  called thunderbolt.
+
+config THUNDERBOLT_ICM
+   tristate "Thunderbolt Networking"
+   help
+ This driver is required if you want Thunderbolt Networking on
+ non-Apple hardware.
+ It creates a virtual Ethernet device that enables computer to
+ computer communication over a Thunderbolt cable.
+
+ To compile this driver as a module, choose M here. The module will be
+ called thunderbolt_icm.
+
+endif
diff --git a/drivers/thunderbolt/Makefile b/drivers/thunderbolt/Makefile
index 5d1053c..b6aa6a3 100644
--- a/drivers/thunderbolt/Makefile
+++ b/drivers/thunderbolt/Makefile
@@ -1,3 +1,4 @@
-obj-${CONFIG_THUNDERBOLT} := thunderbolt.o
+obj-${CONFIG_THUNDERBOLT_APPLE} := thunderbolt.o
 thunderbolt-objs := nhi.o ctl.o tb.o switch.o cap.o path.o tunnel_pci.o 
eeprom.o
 
+obj-${CONFIG_THUNDERBOLT_ICM} += icm/
-- 
2.7.4



[PATCH v9 7/8] thunderbolt: Networking doc

2016-11-09 Thread Amir Levy
Adding Thunderbolt(TM) networking documentation.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 Documentation/00-INDEX   |   2 +
 Documentation/thunderbolt/networking.txt | 132 +++
 2 files changed, 134 insertions(+)
 create mode 100644 Documentation/thunderbolt/networking.txt

diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX
index 3acc4f1..0239e68 100644
--- a/Documentation/00-INDEX
+++ b/Documentation/00-INDEX
@@ -440,6 +440,8 @@ this_cpu_ops.txt
- List rationale behind and the way to use this_cpu operations.
 thermal/
- directory with information on managing thermal issues (CPU/temp)
+thunderbolt/
+   - directory with info regarding Thunderbolt.
 trace/
- directory with info on tracing technologies within linux
 unaligned-memory-access.txt
diff --git a/Documentation/thunderbolt/networking.txt 
b/Documentation/thunderbolt/networking.txt
new file mode 100644
index 000..88d1c12
--- /dev/null
+++ b/Documentation/thunderbolt/networking.txt
@@ -0,0 +1,132 @@
+Intel Thunderbolt(TM) Networking driver
+===
+
+Copyright(c) 2013 - 2016 Intel Corporation.
+
+Contact Information:
+Intel Thunderbolt mailing list <thunderbolt-softw...@lists.01.org>
+Edited by Amir Levy <amir.jer.l...@intel.com>
+
+Overview
+
+
+* The Thunderbolt Networking driver enables peer to peer networking on 
non-Apple
+  platforms running Linux.
+
+* The driver creates a virtual Ethernet device that enables computer to 
computer
+  communication over the Thunderbolt cable.
+
+* Using Thunderbolt Networking you can perform high speed file transfers 
between
+  computers, perform PC migrations and/or set up small workgroups with shared
+  storage without compromising any other Thunderbolt functionality.
+
+* The driver is located in drivers/thunderbolt/icm.
+
+* This driver will function only on non-Apple platforms with firmware based
+  Thunderbolt controllers that support Thunderbolt Networking.
+
+  ++++
+  |Host 1  ||Host 2  |
+  ||||
+  |   +---+||+---+   |
+  |   |Network||||Network|   |
+  |   |Stack  ||||Stack  |   |
+  |   +---+||+---+   |
+  |   ^||^   |
+  |   ||||   |
+  |   v||v   |
+  | +---+  ||  +---+ |
+  | |Thunderbolt|  ||  |Thunderbolt| |
+  | |Networking |  ||  |Networking | |
+  | |Driver |  ||  |Driver | |
+  | +---+  ||  +---+ |
+  |   ^||^   |
+  |   ||||   |
+  |   v||v   |
+  | +---+  ||  +---+ |
+  | |Thunderbolt|  ||  |Thunderbolt| |
+  | |Controller |<-++->|Controller | |
+  | |with ICM   |  ||  |with ICM   | |
+  | |enabled|  ||  |enabled| |
+  | +---+  ||  +---+ |
+  ++++
+
+Files
+=
+
+The following files are located in the drivers/thunderbolt/icm directory:
+
+- icm_nhi.c/h: These files allow communication with the firmware (Intel
+  Connection Manager) based controller. They also create an interface for
+  netlink communication with a user space daemon.
+
+- net.c/net.h: These files implement the 'eth' interface for the
+  Thunderbolt(TM) Networking.
+
+Interface to User Space
+===
+
+The interface to the user space module is implemented through a Generic 
Netlink.
+This is the communications protocol between the Thunderbolt driver and the user
+space application.
+
+Note that this interface mediates user space communication with ICM.
+(Existing Linux tools can be used to configure the network interface.)
+
+The Thunderbolt Daemon utilizes this interface to communicate with the driver.
+To be accessed by the user space module, both kernel and user space modules
+have to register with the same GENL_NAME.
+For the purpose of the Thunderbolt Network driver, "thunderbolt" is used.
+The registration is done at driver initialization time for all instances
+of the Thunderbolt controllers. The communication is carried through 
pre-defined
+Thunderbolt messages. Each specific message has a callback function that is
+called when the related message is received.
+
+Message Definitions:
+* NHI_CMD_UNSPEC: Not used.
+* NHI_CMD_SUBSCRIBE: Subscription request from daemon to driver to open the
+  communication channel.
+* NHI_CMD_UNSUBSCRIBE: Request from daemon to driver to unsubscribe and
+  to close communication channel.
+* NHI_CMD_QUERY_INFORMATION: R

[PATCH v9 2/8] thunderbolt: Updating the register definitions

2016-11-09 Thread Amir Levy
Adding more Thunderbolt(TM) register definitions
and some helper macros.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 drivers/thunderbolt/nhi_regs.h | 109 +
 1 file changed, 109 insertions(+)

diff --git a/drivers/thunderbolt/nhi_regs.h b/drivers/thunderbolt/nhi_regs.h
index 75cf069..b8e961f 100644
--- a/drivers/thunderbolt/nhi_regs.h
+++ b/drivers/thunderbolt/nhi_regs.h
@@ -9,6 +9,11 @@
 
 #include 
 
+#define NHI_MMIO_BAR 0
+
+#define TBT_RING_MIN_NUM_BUFFERS   2
+#define TBT_RING_MAX_FRAME_SIZE(4 * 1024)
+
 enum ring_flags {
RING_FLAG_ISOCH_ENABLE = 1 << 27, /* TX only? */
RING_FLAG_E2E_FLOW_CONTROL = 1 << 28,
@@ -39,6 +44,33 @@ struct ring_desc {
u32 time; /* write zero */
 } __packed;
 
+/**
+ * struct tbt_buf_desc - TX/RX ring buffer descriptor.
+ * This is same as struct ring_desc, but without the use of bitfields and
+ * with explicit endianity.
+ */
+struct tbt_buf_desc {
+   __le64 phys;
+   __le32 attributes;
+   __le32 time;
+};
+
+#define DESC_ATTR_LEN_SHIFT0
+#define DESC_ATTR_LEN_MASK GENMASK(11, DESC_ATTR_LEN_SHIFT)
+#define DESC_ATTR_EOF_SHIFT12
+#define DESC_ATTR_EOF_MASK GENMASK(15, DESC_ATTR_EOF_SHIFT)
+#define DESC_ATTR_SOF_SHIFT16
+#define DESC_ATTR_SOF_MASK GENMASK(19, DESC_ATTR_SOF_SHIFT)
+#define DESC_ATTR_TX_ISOCH_DMA_EN  BIT(20) /* TX */
+#define DESC_ATTR_RX_CRC_ERR   BIT(20) /* RX after use */
+#define DESC_ATTR_DESC_DONEBIT(21)
+#define DESC_ATTR_REQ_STS  BIT(22) /* TX and RX before use */
+#define DESC_ATTR_RX_BUF_OVRN_ERR  BIT(22) /* RX after use */
+#define DESC_ATTR_INT_EN   BIT(23)
+#define DESC_ATTR_OFFSET_SHIFT 24
+#define DESC_ATTR_OFFSET_MASK  GENMASK(31, DESC_ATTR_OFFSET_SHIFT)
+
+
 /* NHI registers in bar 0 */
 
 /*
@@ -60,6 +92,30 @@ struct ring_desc {
  */
 #define REG_RX_RING_BASE   0x08000
 
+#define REG_RING_STEP  16
+#define REG_RING_PHYS_LO_OFFSET0
+#define REG_RING_PHYS_HI_OFFSET4
+#define REG_RING_CONS_PROD_OFFSET  8   /* cons - RO, prod - RW */
+#define REG_RING_CONS_SHIFT0
+#define REG_RING_CONS_MASK GENMASK(15, REG_RING_CONS_SHIFT)
+#define REG_RING_PROD_SHIFT16
+#define REG_RING_PROD_MASK GENMASK(31, REG_RING_PROD_SHIFT)
+#define REG_RING_SIZE_OFFSET   12
+#define REG_RING_SIZE_SHIFT0
+#define REG_RING_SIZE_MASK GENMASK(15, REG_RING_SIZE_SHIFT)
+#define REG_RING_BUF_SIZE_SHIFT16
+#define REG_RING_BUF_SIZE_MASK GENMASK(27, REG_RING_BUF_SIZE_SHIFT)
+
+#define TBT_RING_CONS_PROD_REG(iobase, ringbase, ringnumber) \
+ ((iobase) + (ringbase) + \
+ ((ringnumber) * REG_RING_STEP) + \
+ REG_RING_CONS_PROD_OFFSET)
+
+#define TBT_REG_RING_PROD_EXTRACT(val) (((val) & REG_RING_PROD_MASK) >> \
+  REG_RING_PROD_SHIFT)
+
+#define TBT_REG_RING_CONS_EXTRACT(val) (((val) & REG_RING_CONS_MASK) >> \
+  REG_RING_CONS_SHIFT)
 /*
  * 32 bytes per entry, one entry for every hop (REG_HOP_COUNT)
  * 00: enum_ring_flags
@@ -77,6 +133,19 @@ struct ring_desc {
  * ..: unknown
  */
 #define REG_RX_OPTIONS_BASE0x29800
+#define REG_RX_OPTS_TX_E2E_HOP_ID_SHIFT12
+#define REG_RX_OPTS_TX_E2E_HOP_ID_MASK \
+   GENMASK(22, REG_RX_OPTS_TX_E2E_HOP_ID_SHIFT)
+#define REG_RX_OPTS_MASK_OFFSET4
+#define REG_RX_OPTS_MASK_EOF_SHIFT 0
+#define REG_RX_OPTS_MASK_EOF_MASK  GENMASK(15, REG_RX_OPTS_MASK_EOF_SHIFT)
+#define REG_RX_OPTS_MASK_SOF_SHIFT 16
+#define REG_RX_OPTS_MASK_SOF_MASK  GENMASK(31, REG_RX_OPTS_MASK_SOF_SHIFT)
+
+#define REG_OPTS_STEP  32
+#define REG_OPTS_E2E_ENBIT(28)
+#define REG_OPTS_RAW   BIT(30)
+#define REG_OPTS_VALID BIT(31)
 
 /*
  * three bitfields: tx, rx, rx overflow
@@ -86,6 +155,7 @@ struct ring_desc {
  */
 #define REG_RING_NOTIFY_BASE   0x37800
 #define RING_NOTIFY_REG_COUNT(nhi) ((31 + 3 * nhi->hop_count) / 32)
+#define REG_RING_NOTIFY_STEP   4
 
 /*
  * two bitfields: rx, tx
@@ -94,8 +164,47 @@ struct ring_desc {
  */
 #define REG_RING_INTERRUPT_BASE0x38200
 #define RING_INTERRUPT_REG_COUNT(nhi) ((31 + 2 * nhi->hop_count) / 32)
+#define REG_RING_INT_TX_PROCESSED(ring_num)BIT(ring_num)
+#define REG_RING_INT_RX_PROCESSED(ring_num, num_paths) BIT((ring_num) + \
+   (num_paths))
+#define RING_INT_DISABLE(base, val) iowrite32( \
+   ioread32((base) + REG_RING_INTERRUPT_BASE) & ~(val), \
+   (base) + REG_RING_IN

[PATCH v9 5/8] thunderbolt: Networking transmit and receive

2016-11-09 Thread Amir Levy
This patch provides the handling interface for sending and receiving
network packets between the hosts over the full communication route
(using the communication path established in the previous patch).

The Thunderbolt Network driver interfaces the Linux network stack
and the hardware controller configuration to handle packet transmissions:
  ++++
  |Host 1  ||Host 2  |
  ||||
  |   +---+||+---+   |
  |   |Network||||Network|   |
  |   |Stack  ||||Stack  |   |
  |   +---+||+---+   |
  |   ^||^   |
  |   ||||   |
  |   v||v   |
  | +---+  ||  +---+ |
  | |Thunderbolt|  ||  |Thunderbolt| |
  | |Networking |  ||  |Networking | |
  | |Driver |  ||  |Driver | |
  | +---+  ||  +---+ |
  |   ^||^   |
  |   ||||   |
  |   v||v   |
  | +---+  ||  +---+ |
  | |Thunderbolt|  ||  |Thunderbolt| |
  | |Controller |<-++->|Controller | |
  | +---+  ||  +---+ |
  ++++

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 drivers/thunderbolt/icm/icm_nhi.c |   15 +
 drivers/thunderbolt/icm/net.c | 1471 +
 2 files changed, 1486 insertions(+)

diff --git a/drivers/thunderbolt/icm/icm_nhi.c 
b/drivers/thunderbolt/icm/icm_nhi.c
index edc910b..b1cc347 100644
--- a/drivers/thunderbolt/icm/icm_nhi.c
+++ b/drivers/thunderbolt/icm/icm_nhi.c
@@ -928,6 +928,7 @@ static irqreturn_t nhi_msi(int __always_unused irq, void 
*data)
 {
struct tbt_nhi_ctxt *nhi_ctxt = data;
u32 isr0, isr1, imr0, imr1;
+   int i;
 
/* clear on read */
isr0 = ioread32(nhi_ctxt->iobase + REG_RING_NOTIFY_BASE);
@@ -950,6 +951,20 @@ static irqreturn_t nhi_msi(int __always_unused irq, void 
*data)
 
spin_unlock(_ctxt->lock);
 
+   for (i = 0; i < nhi_ctxt->num_ports; ++i) {
+   struct net_device *net_dev =
+   nhi_ctxt->net_devices[i].net_dev;
+   if (net_dev) {
+   u8 path = PATH_FROM_PORT(nhi_ctxt->num_paths, i);
+
+   if (isr0 & REG_RING_INT_RX_PROCESSED(
+   path, nhi_ctxt->num_paths))
+   tbt_net_rx_msi(net_dev);
+   if (isr0 & REG_RING_INT_TX_PROCESSED(path))
+   tbt_net_tx_msi(net_dev);
+   }
+   }
+
if (isr0 & REG_RING_INT_RX_PROCESSED(TBT_ICM_RING_NUM,
 nhi_ctxt->num_paths))
schedule_work(_ctxt->icm_msgs_work);
diff --git a/drivers/thunderbolt/icm/net.c b/drivers/thunderbolt/icm/net.c
index beeafb3..cf985dd 100644
--- a/drivers/thunderbolt/icm/net.c
+++ b/drivers/thunderbolt/icm/net.c
@@ -124,6 +124,17 @@ struct approve_inter_domain_connection_cmd {
 
 };
 
+struct tbt_frame_header {
+   /* size of the data with the frame */
+   __le32 frame_size;
+   /* running index on the frames */
+   __le16 frame_index;
+   /* ID of the frame to match frames to specific packet */
+   __le16 frame_id;
+   /* how many frames assembles a full packet */
+   __le32 frame_count;
+};
+
 enum neg_event {
RECEIVE_LOGOUT = NUM_MEDIUM_STATUSES,
RECEIVE_LOGIN_RESPONSE,
@@ -131,15 +142,81 @@ enum neg_event {
NUM_NEG_EVENTS
 };
 
+enum frame_status {
+   GOOD_FRAME,
+   GOOD_AS_FIRST_FRAME,
+   GOOD_AS_FIRST_MULTICAST_FRAME,
+   FRAME_NOT_READY,
+   FRAME_ERROR,
+};
+
+enum packet_filter {
+   /* all multicast MAC addresses */
+   PACKET_TYPE_ALL_MULTICAST,
+   /* all types of MAC addresses: multicast, unicast and broadcast */
+   PACKET_TYPE_PROMISCUOUS,
+   /* all unicast MAC addresses */
+   PACKET_TYPE_UNICAST_PROMISCUOUS,
+};
+
 enum disconnect_path_stage {
STAGE_1 = BIT(0),
STAGE_2 = BIT(1)
 };
 
+struct tbt_net_stats {
+   u64 tx_packets;
+   u64 tx_bytes;
+   u64 tx_errors;
+   u64 rx_packets;
+   u64 rx_bytes;
+   u64 rx_length_errors;
+   u64 rx_over_errors;
+   u64 rx_crc_errors;
+   u64 rx_missed_errors;
+   u64 multicast;
+};
+
+static const char tbt_net_gstrings_stats[][ETH_GSTRING_LEN] = {
+   "tx_packets",
+   "tx_bytes",
+   "tx_errors",
+   "rx_packets",
+   "rx_bytes",
+  

[PATCH v9 8/8] thunderbolt: Adding maintainer entry

2016-11-09 Thread Amir Levy
Add Amir Levy as maintainer for Thunderbolt(TM) ICM driver

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 MAINTAINERS | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 411e3b8..87763c44 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10652,7 +10652,13 @@ F: include/uapi/linux/stm.h
 THUNDERBOLT DRIVER
 M: Andreas Noever <andreas.noe...@gmail.com>
 S: Maintained
-F: drivers/thunderbolt/
+F: drivers/thunderbolt/*
+
+THUNDERBOLT ICM DRIVER
+M:     Amir Levy <amir.jer.l...@intel.com>
+S: Maintained
+F: drivers/thunderbolt/icm/
+F: Documentation/thunderbolt/networking.txt
 
 TI BQ27XXX POWER SUPPLY DRIVER
 R: Andrew F. Davis <a...@ti.com>
-- 
2.7.4



[PATCH v9 0/8] thunderbolt: Introducing Thunderbolt(TM) Networking

2016-11-09 Thread Amir Levy
This driver enables Thunderbolt Networking on non-Apple platforms
running Linux.

Thunderbolt Networking provides peer-to-peer connections to transfer
files between computers, perform PC migrations, and/or set up small
workgroups with shared storage.

This is a virtual connection that emulates an Ethernet adapter that
enables Ethernet networking with the benefit of Thunderbolt superfast
medium capability.

Thunderbolt Networking enables two hosts and several devices that
have a Thunderbolt controller to be connected together in a linear
(Daisy chain) series from a single port.

Thunderbolt Networking for Linux is compatible with Thunderbolt
Networking on systems running macOS or Windows and also supports
Thunderbolt generation 2 and 3 controllers.

Note that all pre-existing Thunderbolt generation 3 features, such as
USB, Display and other Thunderbolt device connectivity will continue
to function exactly as they did prior to enabling Thunderbolt Networking.

Code and Software Specifications:
This kernel code creates a virtual ethernet device for computer to
computer communication over a Thunderbolt cable.
The new driver is a separate driver to the existing Thunderbolt driver.
It is designed to work on systems running Linux that
interface with Intel Connection Manager (ICM) firmware based
Thunderbolt controllers that support Thunderbolt Networking.
The kernel code operates in coordination with the Thunderbolt user-
space daemon to implement full Thunderbolt networking functionality.

Hardware Specifications:
Thunderbolt Hardware specs have not yet been published but are used
where necessary for register definitions. 

Acked-by: Andreas Noever <andreas.noe...@gmail.com>
Tested-by: Mario Limonciello <mario.limoncie...@dell.com>

Changes since v8:
 - Added support for more Thunderbolt device IDs

These patches were pushed to GitHub where they can be reviewed more
comfortably with green/red highlighting:
https://github.com/01org/thunderbolt-software-kernel-tree

Daemon code:
https://github.com/01org/thunderbolt-software-daemon

For reference, here's a link to version 8:
[v8]:   https://lkml.org/lkml/2016/9/28/378

Amir Levy (8):
  thunderbolt: Macro rename
  thunderbolt: Updating the register definitions
  thunderbolt: Communication with the ICM (firmware)
  thunderbolt: Networking state machine
  thunderbolt: Networking transmit and receive
  thunderbolt: Kconfig for Thunderbolt Networking
  thunderbolt: Networking doc
  thunderbolt: Adding maintainer entry

 Documentation/00-INDEX   |2 +
 Documentation/thunderbolt/networking.txt |  132 ++
 MAINTAINERS  |8 +-
 drivers/thunderbolt/Kconfig  |   27 +-
 drivers/thunderbolt/Makefile |3 +-
 drivers/thunderbolt/icm/Makefile |2 +
 drivers/thunderbolt/icm/icm_nhi.c| 1520 
 drivers/thunderbolt/icm/icm_nhi.h|   85 ++
 drivers/thunderbolt/icm/net.c| 2254 ++
 drivers/thunderbolt/icm/net.h|  287 
 drivers/thunderbolt/nhi_regs.h   |  115 +-
 11 files changed, 4426 insertions(+), 9 deletions(-)
 create mode 100644 Documentation/thunderbolt/networking.txt
 create mode 100644 drivers/thunderbolt/icm/Makefile
 create mode 100644 drivers/thunderbolt/icm/icm_nhi.c
 create mode 100644 drivers/thunderbolt/icm/icm_nhi.h
 create mode 100644 drivers/thunderbolt/icm/net.c
 create mode 100644 drivers/thunderbolt/icm/net.h

-- 
2.7.4



[PATCH v9 3/8] thunderbolt: Communication with the ICM (firmware)

2016-11-09 Thread Amir Levy
This patch provides the communication protocol between the
Intel Connection Manager(ICM) firmware that is operational in the
Thunderbolt controller in non-Apple hardware.
The ICM firmware-based controller is used for establishing and maintaining
the Thunderbolt Networking connection - we need to be able to communicate
with it.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 drivers/thunderbolt/icm/Makefile  |2 +
 drivers/thunderbolt/icm/icm_nhi.c | 1257 +
 drivers/thunderbolt/icm/icm_nhi.h |   85 +++
 drivers/thunderbolt/icm/net.h |  217 +++
 4 files changed, 1561 insertions(+)
 create mode 100644 drivers/thunderbolt/icm/Makefile
 create mode 100644 drivers/thunderbolt/icm/icm_nhi.c
 create mode 100644 drivers/thunderbolt/icm/icm_nhi.h
 create mode 100644 drivers/thunderbolt/icm/net.h

diff --git a/drivers/thunderbolt/icm/Makefile b/drivers/thunderbolt/icm/Makefile
new file mode 100644
index 000..f0d0fbb
--- /dev/null
+++ b/drivers/thunderbolt/icm/Makefile
@@ -0,0 +1,2 @@
+obj-${CONFIG_THUNDERBOLT_ICM} += thunderbolt-icm.o
+thunderbolt-icm-objs := icm_nhi.o
diff --git a/drivers/thunderbolt/icm/icm_nhi.c 
b/drivers/thunderbolt/icm/icm_nhi.c
new file mode 100644
index 000..c843ce8
--- /dev/null
+++ b/drivers/thunderbolt/icm/icm_nhi.c
@@ -0,0 +1,1257 @@
+/***
+ *
+ * Intel Thunderbolt(TM) driver
+ * Copyright(c) 2014 - 2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ 
**/
+
+#include 
+#include 
+#include 
+#include 
+#include "icm_nhi.h"
+#include "net.h"
+
+#define NHI_GENL_VERSION 1
+#define NHI_GENL_NAME "thunderbolt"
+
+#define DEVICE_DATA(num_ports, dma_port, nvm_ver_offset, nvm_auth_on_boot,\
+   support_full_e2e) \
+   ((num_ports) | ((dma_port) << 4) | ((nvm_ver_offset) << 10) | \
+((nvm_auth_on_boot) << 22) | ((support_full_e2e) << 23))
+#define DEVICE_DATA_NUM_PORTS(device_data) ((device_data) & 0xf)
+#define DEVICE_DATA_DMA_PORT(device_data) (((device_data) >> 4) & 0x3f)
+#define DEVICE_DATA_NVM_VER_OFFSET(device_data) (((device_data) >> 10) & 0xfff)
+#define DEVICE_DATA_NVM_AUTH_ON_BOOT(device_data) (((device_data) >> 22) & 0x1)
+#define DEVICE_DATA_SUPPORT_FULL_E2E(device_data) (((device_data) >> 23) & 0x1)
+
+#define USEC_TO_256_NSECS(usec) DIV_ROUND_UP((usec) * NSEC_PER_USEC, 256)
+
+/* NHI genetlink commands */
+enum {
+   NHI_CMD_UNSPEC,
+   NHI_CMD_SUBSCRIBE,
+   NHI_CMD_UNSUBSCRIBE,
+   NHI_CMD_QUERY_INFORMATION,
+   NHI_CMD_MSG_TO_ICM,
+   NHI_CMD_MSG_FROM_ICM,
+   NHI_CMD_MAILBOX,
+   NHI_CMD_APPROVE_TBT_NETWORKING,
+   NHI_CMD_ICM_IN_SAFE_MODE,
+   __NHI_CMD_MAX,
+};
+#define NHI_CMD_MAX (__NHI_CMD_MAX - 1)
+
+/* NHI genetlink policy */
+static const struct nla_policy nhi_genl_policy[NHI_ATTR_MAX + 1] = {
+   [NHI_ATTR_DRV_VERSION]  = { .type = NLA_NUL_STRING, },
+   [NHI_ATTR_NVM_VER_OFFSET]   = { .type = NLA_U16, },
+   [NHI_ATTR_NUM_PORTS]= { .type = NLA_U8, },
+   [NHI_ATTR_DMA_PORT] = { .type = NLA_U8, },
+   [NHI_ATTR_SUPPORT_FULL_E2E] = { .type = NLA_FLAG, },
+   [NHI_ATTR_MAILBOX_CMD]  = { .type = NLA_U32, },
+   [NHI_ATTR_PDF]  = { .type = NLA_U32, },
+   [NHI_ATTR_MSG_TO_ICM]   = { .type = NLA_BINARY,
+   .len = TBT_ICM_RING_MAX_FRAME_SIZE },
+   [NHI_ATTR_MSG_FROM_ICM] = { .type = NLA_BINARY,
+   .len = TBT_ICM_RING_MAX_FRAME_SIZE },
+};
+
+/* NHI genetlink family */
+static struct genl_family nhi_genl_family = {
+   .id = GENL_ID_GENERATE,
+   .hdrsize= FIELD_SIZEOF(struct tbt_nhi_ctxt, id),
+   .name   = NHI_GENL_NAME,
+   .version= NHI_GENL_VERSION,
+   .maxattr= NHI_ATTR_MAX,
+};
+
+static LIST_HEAD(controllers_list);
+static DEFINE_MUTEX(controllers_list_mutex);
+static atomic_t subscribers = ATOMIC_INIT(0);
+/*
+ * Some of the received generic netlink messages are replied in a different
+ * context. The reply has to include the netlink portid of sender, therefore
+ * saving it in global variable (current assuption is one sender).
+ */
+static u32 portid;
+
+static bool nhi_nvm_authenticated(struct

[PATCH v8 1/8] thunderbolt: Macro rename

2016-09-28 Thread Amir Levy
This first patch updates the NHI Thunderbolt controller registers file to
reflect that it is not only for Cactus Ridge.
No functional change intended.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
Signed-off-by: Andreas Noever <andreas.noe...@gmail.com>
---
 drivers/thunderbolt/nhi_regs.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/thunderbolt/nhi_regs.h b/drivers/thunderbolt/nhi_regs.h
index 86b996c..75cf069 100644
--- a/drivers/thunderbolt/nhi_regs.h
+++ b/drivers/thunderbolt/nhi_regs.h
@@ -1,11 +1,11 @@
 /*
- * Thunderbolt Cactus Ridge driver - NHI registers
+ * Thunderbolt driver - NHI registers
  *
  * Copyright (c) 2014 Andreas Noever <andreas.noe...@gmail.com>
  */
 
-#ifndef DSL3510_REGS_H_
-#define DSL3510_REGS_H_
+#ifndef NHI_REGS_H_
+#define NHI_REGS_H_
 
 #include 
 
-- 
2.7.4



[PATCH v8 4/8] thunderbolt: Networking state machine

2016-09-28 Thread Amir Levy
This patch builds the peer to peer communication path.
Communication is established by a negotiation process whereby messages are
sent back and forth between the peers until a connection is established.
This includes the Thunderbolt Network driver communication with the second
peer via Intel Connection Manager(ICM) firmware.
  ++++
  |Host 1  ||Host 2  |
  ||||
  | +---+  || +---+  |
  | |Thunderbolt|  || |Thunderbolt|  |
  | |Networking |  || |Networking |  |
  | |Driver |  || |Driver |  |
  | +---+  || +---+  |
  |  ^ ||  ^ |
  |  | ||  | |
  | ++---+ || ++---+ |
  | |Thunderbolt |   | || |Thunderbolt |   | |
  | |Controller  v   | || |Controller  v   | |
  | | +---+  | || | +---+  | |
  | | |ICM|<-+-++-+>|ICM|  | |
  | | +---+  | || | +---+  | |
  | ++ || ++ |
  ++++
Note that this patch only establishes the link between the two hosts and
not Network Packet handling - this is dealt with in the next patch.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 drivers/thunderbolt/icm/Makefile  |   2 +-
 drivers/thunderbolt/icm/icm_nhi.c | 262 -
 drivers/thunderbolt/icm/net.c | 783 ++
 drivers/thunderbolt/icm/net.h |  70 
 4 files changed, 1109 insertions(+), 8 deletions(-)
 create mode 100644 drivers/thunderbolt/icm/net.c

diff --git a/drivers/thunderbolt/icm/Makefile b/drivers/thunderbolt/icm/Makefile
index f0d0fbb..94a2797 100644
--- a/drivers/thunderbolt/icm/Makefile
+++ b/drivers/thunderbolt/icm/Makefile
@@ -1,2 +1,2 @@
 obj-${CONFIG_THUNDERBOLT_ICM} += thunderbolt-icm.o
-thunderbolt-icm-objs := icm_nhi.o
+thunderbolt-icm-objs := icm_nhi.o net.o
diff --git a/drivers/thunderbolt/icm/icm_nhi.c 
b/drivers/thunderbolt/icm/icm_nhi.c
index 23047d3..a849698 100644
--- a/drivers/thunderbolt/icm/icm_nhi.c
+++ b/drivers/thunderbolt/icm/icm_nhi.c
@@ -64,6 +64,13 @@ static const struct nla_policy nhi_genl_policy[NHI_ATTR_MAX 
+ 1] = {
.len = TBT_ICM_RING_MAX_FRAME_SIZE },
[NHI_ATTR_MSG_FROM_ICM] = { .type = NLA_BINARY,
.len = TBT_ICM_RING_MAX_FRAME_SIZE },
+   [NHI_ATTR_LOCAL_ROUTE_STRING]   = {
+   .len = sizeof(struct route_string) },
+   [NHI_ATTR_LOCAL_UUID]   = { .len = sizeof(uuid_be) },
+   [NHI_ATTR_REMOTE_UUID]  = { .len = sizeof(uuid_be) },
+   [NHI_ATTR_LOCAL_DEPTH]  = { .type = NLA_U8, },
+   [NHI_ATTR_ENABLE_FULL_E2E]  = { .type = NLA_FLAG, },
+   [NHI_ATTR_MATCH_FRAME_ID]   = { .type = NLA_FLAG, },
 };
 
 /* NHI genetlink family */
@@ -480,6 +487,29 @@ int nhi_mailbox(struct tbt_nhi_ctxt *nhi_ctxt, u32 cmd, 
u32 data, bool deinit)
return 0;
 }
 
+static inline bool nhi_is_path_disconnected(u32 cmd, u8 num_ports)
+{
+   return (cmd >= DISCONNECT_PORT_A_INTER_DOMAIN_PATH &&
+   cmd < (DISCONNECT_PORT_A_INTER_DOMAIN_PATH + num_ports));
+}
+
+static int nhi_mailbox_disconn_path(struct tbt_nhi_ctxt *nhi_ctxt, u32 cmd)
+   __releases(_list_mutex)
+{
+   struct port_net_dev *port;
+   u32 port_num = cmd - DISCONNECT_PORT_A_INTER_DOMAIN_PATH;
+
+   port = &(nhi_ctxt->net_devices[port_num]);
+   mutex_lock(>state_mutex);
+
+   mutex_unlock(_list_mutex);
+   port->medium_sts = MEDIUM_READY_FOR_APPROVAL;
+   if (port->net_dev)
+   negotiation_events(port->net_dev, MEDIUM_DISCONNECTED);
+   mutex_unlock(>state_mutex);
+   return  0;
+}
+
 static int nhi_mailbox_generic(struct tbt_nhi_ctxt *nhi_ctxt, u32 mb_cmd)
__releases(_list_mutex)
 {
@@ -526,13 +556,90 @@ static int nhi_genl_mailbox(__always_unused struct 
sk_buff *u_skb,
return -ERESTART;
 
nhi_ctxt = nhi_search_ctxt(*(u32 *)info->userhdr);
-   if (nhi_ctxt && !nhi_ctxt->d0_exit)
-   return nhi_mailbox_generic(nhi_ctxt, mb_cmd);
+   if (nhi_ctxt && !nhi_ctxt->d0_exit) {
+
+   /* rwsem is released later by the below functions */
+   if (nhi_is_path_disconnected(cmd, nhi_ctxt->num_ports))
+   return nhi_mailbox_disconn_path(nhi_ctxt, cmd);
+   else
+   return nhi_mailbox_generic(nhi_ctxt, mb_cmd);
+
+   }
 
mutex_unlock(_list_

[PATCH v8 6/8] thunderbolt: Kconfig for Thunderbolt Networking

2016-09-28 Thread Amir Levy
Update to the Kconfig Thunderbolt description to add
Thunderbolt networking as an option.
The menu item "Thunderbolt support" now offers:
"Apple Hardware Support" (existing)
and/or
"Thunderbolt Networking" (new)

You can choose the driver for your platform or build both drivers -
each driver will detect if it can run on the specific platform.
If the Thunderbolt Networking option is chosen, Thunderbolt Networking
will be enabled between Linux non-Apple systems, macOS and
Windows based systems.
Thunderbolt Networking will not affect any other Thunderbolt feature that
was previous available to Linux users on either Apple or
non-Apple platforms.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 drivers/thunderbolt/Kconfig  | 27 +++
 drivers/thunderbolt/Makefile |  3 ++-
 2 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/drivers/thunderbolt/Kconfig b/drivers/thunderbolt/Kconfig
index c121acc..376e5bb 100644
--- a/drivers/thunderbolt/Kconfig
+++ b/drivers/thunderbolt/Kconfig
@@ -1,13 +1,32 @@
-menuconfig THUNDERBOLT
-   tristate "Thunderbolt support for Apple devices"
+config THUNDERBOLT
+   tristate "Thunderbolt support"
depends on PCI
select CRC32
help
- Cactus Ridge Thunderbolt Controller driver
+ Thunderbolt Controller driver
+
+if THUNDERBOLT
+
+config THUNDERBOLT_APPLE
+   tristate "Apple hardware support"
+   help
  This driver is required if you want to hotplug Thunderbolt devices on
  Apple hardware.
 
  Device chaining is currently not supported.
 
- To compile this driver a module, choose M here. The module will be
+ To compile this driver as a module, choose M here. The module will be
  called thunderbolt.
+
+config THUNDERBOLT_ICM
+   tristate "Thunderbolt Networking"
+   help
+ This driver is required if you want Thunderbolt Networking on
+ non-Apple hardware.
+ It creates a virtual Ethernet device that enables computer to
+ computer communication over a Thunderbolt cable.
+
+ To compile this driver as a module, choose M here. The module will be
+ called thunderbolt_icm.
+
+endif
diff --git a/drivers/thunderbolt/Makefile b/drivers/thunderbolt/Makefile
index 5d1053c..b6aa6a3 100644
--- a/drivers/thunderbolt/Makefile
+++ b/drivers/thunderbolt/Makefile
@@ -1,3 +1,4 @@
-obj-${CONFIG_THUNDERBOLT} := thunderbolt.o
+obj-${CONFIG_THUNDERBOLT_APPLE} := thunderbolt.o
 thunderbolt-objs := nhi.o ctl.o tb.o switch.o cap.o path.o tunnel_pci.o 
eeprom.o
 
+obj-${CONFIG_THUNDERBOLT_ICM} += icm/
-- 
2.7.4



[PATCH v8 7/8] thunderbolt: Networking doc

2016-09-28 Thread Amir Levy
Adding Thunderbolt(TM) networking documentation.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 Documentation/00-INDEX   |   2 +
 Documentation/thunderbolt/networking.txt | 132 +++
 2 files changed, 134 insertions(+)
 create mode 100644 Documentation/thunderbolt/networking.txt

diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX
index cb9a6c6..a448ba1 100644
--- a/Documentation/00-INDEX
+++ b/Documentation/00-INDEX
@@ -439,6 +439,8 @@ this_cpu_ops.txt
- List rationale behind and the way to use this_cpu operations.
 thermal/
- directory with information on managing thermal issues (CPU/temp)
+thunderbolt/
+   - directory with info regarding Thunderbolt.
 trace/
- directory with info on tracing technologies within linux
 unaligned-memory-access.txt
diff --git a/Documentation/thunderbolt/networking.txt 
b/Documentation/thunderbolt/networking.txt
new file mode 100644
index 000..88d1c12
--- /dev/null
+++ b/Documentation/thunderbolt/networking.txt
@@ -0,0 +1,132 @@
+Intel Thunderbolt(TM) Networking driver
+===
+
+Copyright(c) 2013 - 2016 Intel Corporation.
+
+Contact Information:
+Intel Thunderbolt mailing list <thunderbolt-softw...@lists.01.org>
+Edited by Amir Levy <amir.jer.l...@intel.com>
+
+Overview
+
+
+* The Thunderbolt Networking driver enables peer to peer networking on 
non-Apple
+  platforms running Linux.
+
+* The driver creates a virtual Ethernet device that enables computer to 
computer
+  communication over the Thunderbolt cable.
+
+* Using Thunderbolt Networking you can perform high speed file transfers 
between
+  computers, perform PC migrations and/or set up small workgroups with shared
+  storage without compromising any other Thunderbolt functionality.
+
+* The driver is located in drivers/thunderbolt/icm.
+
+* This driver will function only on non-Apple platforms with firmware based
+  Thunderbolt controllers that support Thunderbolt Networking.
+
+  ++++
+  |Host 1  ||Host 2  |
+  ||||
+  |   +---+||+---+   |
+  |   |Network||||Network|   |
+  |   |Stack  ||||Stack  |   |
+  |   +---+||+---+   |
+  |   ^||^   |
+  |   ||||   |
+  |   v||v   |
+  | +---+  ||  +---+ |
+  | |Thunderbolt|  ||  |Thunderbolt| |
+  | |Networking |  ||  |Networking | |
+  | |Driver |  ||  |Driver | |
+  | +---+  ||  +---+ |
+  |   ^||^   |
+  |   ||||   |
+  |   v||v   |
+  | +---+  ||  +---+ |
+  | |Thunderbolt|  ||  |Thunderbolt| |
+  | |Controller |<-++->|Controller | |
+  | |with ICM   |  ||  |with ICM   | |
+  | |enabled|  ||  |enabled| |
+  | +---+  ||  +---+ |
+  ++++
+
+Files
+=
+
+The following files are located in the drivers/thunderbolt/icm directory:
+
+- icm_nhi.c/h: These files allow communication with the firmware (Intel
+  Connection Manager) based controller. They also create an interface for
+  netlink communication with a user space daemon.
+
+- net.c/net.h: These files implement the 'eth' interface for the
+  Thunderbolt(TM) Networking.
+
+Interface to User Space
+===
+
+The interface to the user space module is implemented through a Generic 
Netlink.
+This is the communications protocol between the Thunderbolt driver and the user
+space application.
+
+Note that this interface mediates user space communication with ICM.
+(Existing Linux tools can be used to configure the network interface.)
+
+The Thunderbolt Daemon utilizes this interface to communicate with the driver.
+To be accessed by the user space module, both kernel and user space modules
+have to register with the same GENL_NAME.
+For the purpose of the Thunderbolt Network driver, "thunderbolt" is used.
+The registration is done at driver initialization time for all instances
+of the Thunderbolt controllers. The communication is carried through 
pre-defined
+Thunderbolt messages. Each specific message has a callback function that is
+called when the related message is received.
+
+Message Definitions:
+* NHI_CMD_UNSPEC: Not used.
+* NHI_CMD_SUBSCRIBE: Subscription request from daemon to driver to open the
+  communication channel.
+* NHI_CMD_UNSUBSCRIBE: Request from daemon to driver to unsubscribe and
+  to close communication channel.
+* NHI_CMD_QUERY_INFORMATION: R

[PATCH v8 3/8] thunderbolt: Communication with the ICM (firmware)

2016-09-28 Thread Amir Levy
This patch provides the communication protocol between the
Intel Connection Manager(ICM) firmware that is operational in the
Thunderbolt controller in non-Apple hardware.
The ICM firmware-based controller is used for establishing and maintaining
the Thunderbolt Networking connection - we need to be able to communicate
with it.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 drivers/thunderbolt/icm/Makefile  |2 +
 drivers/thunderbolt/icm/icm_nhi.c | 1251 +
 drivers/thunderbolt/icm/icm_nhi.h |   82 +++
 drivers/thunderbolt/icm/net.h |  217 +++
 4 files changed, 1552 insertions(+)
 create mode 100644 drivers/thunderbolt/icm/Makefile
 create mode 100644 drivers/thunderbolt/icm/icm_nhi.c
 create mode 100644 drivers/thunderbolt/icm/icm_nhi.h
 create mode 100644 drivers/thunderbolt/icm/net.h

diff --git a/drivers/thunderbolt/icm/Makefile b/drivers/thunderbolt/icm/Makefile
new file mode 100644
index 000..f0d0fbb
--- /dev/null
+++ b/drivers/thunderbolt/icm/Makefile
@@ -0,0 +1,2 @@
+obj-${CONFIG_THUNDERBOLT_ICM} += thunderbolt-icm.o
+thunderbolt-icm-objs := icm_nhi.o
diff --git a/drivers/thunderbolt/icm/icm_nhi.c 
b/drivers/thunderbolt/icm/icm_nhi.c
new file mode 100644
index 000..23047d3
--- /dev/null
+++ b/drivers/thunderbolt/icm/icm_nhi.c
@@ -0,0 +1,1251 @@
+/***
+ *
+ * Intel Thunderbolt(TM) driver
+ * Copyright(c) 2014 - 2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ 
**/
+
+#include 
+#include 
+#include 
+#include 
+#include "icm_nhi.h"
+#include "net.h"
+
+#define NHI_GENL_VERSION 1
+#define NHI_GENL_NAME "thunderbolt"
+
+#define DEVICE_DATA(num_ports, dma_port, nvm_ver_offset, nvm_auth_on_boot,\
+   support_full_e2e) \
+   ((num_ports) | ((dma_port) << 4) | ((nvm_ver_offset) << 10) | \
+((nvm_auth_on_boot) << 22) | ((support_full_e2e) << 23))
+#define DEVICE_DATA_NUM_PORTS(device_data) ((device_data) & 0xf)
+#define DEVICE_DATA_DMA_PORT(device_data) (((device_data) >> 4) & 0x3f)
+#define DEVICE_DATA_NVM_VER_OFFSET(device_data) (((device_data) >> 10) & 0xfff)
+#define DEVICE_DATA_NVM_AUTH_ON_BOOT(device_data) (((device_data) >> 22) & 0x1)
+#define DEVICE_DATA_SUPPORT_FULL_E2E(device_data) (((device_data) >> 23) & 0x1)
+
+#define USEC_TO_256_NSECS(usec) DIV_ROUND_UP((usec) * NSEC_PER_USEC, 256)
+
+/* NHI genetlink commands */
+enum {
+   NHI_CMD_UNSPEC,
+   NHI_CMD_SUBSCRIBE,
+   NHI_CMD_UNSUBSCRIBE,
+   NHI_CMD_QUERY_INFORMATION,
+   NHI_CMD_MSG_TO_ICM,
+   NHI_CMD_MSG_FROM_ICM,
+   NHI_CMD_MAILBOX,
+   NHI_CMD_APPROVE_TBT_NETWORKING,
+   NHI_CMD_ICM_IN_SAFE_MODE,
+   __NHI_CMD_MAX,
+};
+#define NHI_CMD_MAX (__NHI_CMD_MAX - 1)
+
+/* NHI genetlink policy */
+static const struct nla_policy nhi_genl_policy[NHI_ATTR_MAX + 1] = {
+   [NHI_ATTR_DRV_VERSION]  = { .type = NLA_NUL_STRING, },
+   [NHI_ATTR_NVM_VER_OFFSET]   = { .type = NLA_U16, },
+   [NHI_ATTR_NUM_PORTS]= { .type = NLA_U8, },
+   [NHI_ATTR_DMA_PORT] = { .type = NLA_U8, },
+   [NHI_ATTR_SUPPORT_FULL_E2E] = { .type = NLA_FLAG, },
+   [NHI_ATTR_MAILBOX_CMD]  = { .type = NLA_U32, },
+   [NHI_ATTR_PDF]  = { .type = NLA_U32, },
+   [NHI_ATTR_MSG_TO_ICM]   = { .type = NLA_BINARY,
+   .len = TBT_ICM_RING_MAX_FRAME_SIZE },
+   [NHI_ATTR_MSG_FROM_ICM] = { .type = NLA_BINARY,
+   .len = TBT_ICM_RING_MAX_FRAME_SIZE },
+};
+
+/* NHI genetlink family */
+static struct genl_family nhi_genl_family = {
+   .id = GENL_ID_GENERATE,
+   .hdrsize= FIELD_SIZEOF(struct tbt_nhi_ctxt, id),
+   .name   = NHI_GENL_NAME,
+   .version= NHI_GENL_VERSION,
+   .maxattr= NHI_ATTR_MAX,
+};
+
+static LIST_HEAD(controllers_list);
+static DEFINE_MUTEX(controllers_list_mutex);
+static atomic_t subscribers = ATOMIC_INIT(0);
+/*
+ * Some of the received generic netlink messages are replied in a different
+ * context. The reply has to include the netlink portid of sender, therefore
+ * saving it in global variable (current assuption is one sender).
+ */
+static u32 portid;
+
+static bool nhi_nvm_authenticated(struct

[PATCH v8 8/8] thunderbolt: Adding maintainer entry

2016-09-28 Thread Amir Levy
Add Amir Levy as maintainer for Thunderbolt(TM) ICM driver

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 MAINTAINERS | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 01bff8e..a4a4614 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10358,7 +10358,13 @@ F: include/uapi/linux/stm.h
 THUNDERBOLT DRIVER
 M: Andreas Noever <andreas.noe...@gmail.com>
 S: Maintained
-F: drivers/thunderbolt/
+F: drivers/thunderbolt/*
+
+THUNDERBOLT ICM DRIVER
+M:     Amir Levy <amir.jer.l...@intel.com>
+S: Maintained
+F: drivers/thunderbolt/icm/
+F: Documentation/thunderbolt/networking.txt
 
 TI BQ27XXX POWER SUPPLY DRIVER
 R: Andrew F. Davis <a...@ti.com>
-- 
2.7.4



[PATCH v8 5/8] thunderbolt: Networking transmit and receive

2016-09-28 Thread Amir Levy
This patch provides the handling interface for sending and receiving
network packets between the hosts over the full communication route
(using the communication path established in the previous patch).

The Thunderbolt Network driver interfaces the Linux network stack
and the hardware controller configuration to handle packet transmissions:
  ++++
  |Host 1  ||Host 2  |
  ||||
  |   +---+||+---+   |
  |   |Network||||Network|   |
  |   |Stack  ||||Stack  |   |
  |   +---+||+---+   |
  |   ^||^   |
  |   ||||   |
  |   v||v   |
  | +---+  ||  +---+ |
  | |Thunderbolt|  ||  |Thunderbolt| |
  | |Networking |  ||  |Networking | |
  | |Driver |  ||  |Driver | |
  | +---+  ||  +---+ |
  |   ^||^   |
  |   ||||   |
  |   v||v   |
  | +---+  ||  +---+ |
  | |Thunderbolt|  ||  |Thunderbolt| |
  | |Controller |<-++->|Controller | |
  | +---+  ||  +---+ |
  ++++

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 drivers/thunderbolt/icm/icm_nhi.c |   15 +
 drivers/thunderbolt/icm/net.c | 1471 +
 2 files changed, 1486 insertions(+)

diff --git a/drivers/thunderbolt/icm/icm_nhi.c 
b/drivers/thunderbolt/icm/icm_nhi.c
index a849698..5148081 100644
--- a/drivers/thunderbolt/icm/icm_nhi.c
+++ b/drivers/thunderbolt/icm/icm_nhi.c
@@ -928,6 +928,7 @@ static irqreturn_t nhi_msi(int __always_unused irq, void 
*data)
 {
struct tbt_nhi_ctxt *nhi_ctxt = data;
u32 isr0, isr1, imr0, imr1;
+   int i;
 
/* clear on read */
isr0 = ioread32(nhi_ctxt->iobase + REG_RING_NOTIFY_BASE);
@@ -950,6 +951,20 @@ static irqreturn_t nhi_msi(int __always_unused irq, void 
*data)
 
spin_unlock(_ctxt->lock);
 
+   for (i = 0; i < nhi_ctxt->num_ports; ++i) {
+   struct net_device *net_dev =
+   nhi_ctxt->net_devices[i].net_dev;
+   if (net_dev) {
+   u8 path = PATH_FROM_PORT(nhi_ctxt->num_paths, i);
+
+   if (isr0 & REG_RING_INT_RX_PROCESSED(
+   path, nhi_ctxt->num_paths))
+   tbt_net_rx_msi(net_dev);
+   if (isr0 & REG_RING_INT_TX_PROCESSED(path))
+   tbt_net_tx_msi(net_dev);
+   }
+   }
+
if (isr0 & REG_RING_INT_RX_PROCESSED(TBT_ICM_RING_NUM,
 nhi_ctxt->num_paths))
schedule_work(_ctxt->icm_msgs_work);
diff --git a/drivers/thunderbolt/icm/net.c b/drivers/thunderbolt/icm/net.c
index beeafb3..cf985dd 100644
--- a/drivers/thunderbolt/icm/net.c
+++ b/drivers/thunderbolt/icm/net.c
@@ -124,6 +124,17 @@ struct approve_inter_domain_connection_cmd {
 
 };
 
+struct tbt_frame_header {
+   /* size of the data with the frame */
+   __le32 frame_size;
+   /* running index on the frames */
+   __le16 frame_index;
+   /* ID of the frame to match frames to specific packet */
+   __le16 frame_id;
+   /* how many frames assembles a full packet */
+   __le32 frame_count;
+};
+
 enum neg_event {
RECEIVE_LOGOUT = NUM_MEDIUM_STATUSES,
RECEIVE_LOGIN_RESPONSE,
@@ -131,15 +142,81 @@ enum neg_event {
NUM_NEG_EVENTS
 };
 
+enum frame_status {
+   GOOD_FRAME,
+   GOOD_AS_FIRST_FRAME,
+   GOOD_AS_FIRST_MULTICAST_FRAME,
+   FRAME_NOT_READY,
+   FRAME_ERROR,
+};
+
+enum packet_filter {
+   /* all multicast MAC addresses */
+   PACKET_TYPE_ALL_MULTICAST,
+   /* all types of MAC addresses: multicast, unicast and broadcast */
+   PACKET_TYPE_PROMISCUOUS,
+   /* all unicast MAC addresses */
+   PACKET_TYPE_UNICAST_PROMISCUOUS,
+};
+
 enum disconnect_path_stage {
STAGE_1 = BIT(0),
STAGE_2 = BIT(1)
 };
 
+struct tbt_net_stats {
+   u64 tx_packets;
+   u64 tx_bytes;
+   u64 tx_errors;
+   u64 rx_packets;
+   u64 rx_bytes;
+   u64 rx_length_errors;
+   u64 rx_over_errors;
+   u64 rx_crc_errors;
+   u64 rx_missed_errors;
+   u64 multicast;
+};
+
+static const char tbt_net_gstrings_stats[][ETH_GSTRING_LEN] = {
+   "tx_packets",
+   "tx_bytes",
+   "tx_errors",
+   "rx_packets",
+   "rx_bytes",
+  

[PATCH v8 2/8] thunderbolt: Updating the register definitions

2016-09-28 Thread Amir Levy
Adding more Thunderbolt(TM) register definitions
and some helper macros.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 drivers/thunderbolt/nhi_regs.h | 109 +
 1 file changed, 109 insertions(+)

diff --git a/drivers/thunderbolt/nhi_regs.h b/drivers/thunderbolt/nhi_regs.h
index 75cf069..b8e961f 100644
--- a/drivers/thunderbolt/nhi_regs.h
+++ b/drivers/thunderbolt/nhi_regs.h
@@ -9,6 +9,11 @@
 
 #include 
 
+#define NHI_MMIO_BAR 0
+
+#define TBT_RING_MIN_NUM_BUFFERS   2
+#define TBT_RING_MAX_FRAME_SIZE(4 * 1024)
+
 enum ring_flags {
RING_FLAG_ISOCH_ENABLE = 1 << 27, /* TX only? */
RING_FLAG_E2E_FLOW_CONTROL = 1 << 28,
@@ -39,6 +44,33 @@ struct ring_desc {
u32 time; /* write zero */
 } __packed;
 
+/**
+ * struct tbt_buf_desc - TX/RX ring buffer descriptor.
+ * This is same as struct ring_desc, but without the use of bitfields and
+ * with explicit endianity.
+ */
+struct tbt_buf_desc {
+   __le64 phys;
+   __le32 attributes;
+   __le32 time;
+};
+
+#define DESC_ATTR_LEN_SHIFT0
+#define DESC_ATTR_LEN_MASK GENMASK(11, DESC_ATTR_LEN_SHIFT)
+#define DESC_ATTR_EOF_SHIFT12
+#define DESC_ATTR_EOF_MASK GENMASK(15, DESC_ATTR_EOF_SHIFT)
+#define DESC_ATTR_SOF_SHIFT16
+#define DESC_ATTR_SOF_MASK GENMASK(19, DESC_ATTR_SOF_SHIFT)
+#define DESC_ATTR_TX_ISOCH_DMA_EN  BIT(20) /* TX */
+#define DESC_ATTR_RX_CRC_ERR   BIT(20) /* RX after use */
+#define DESC_ATTR_DESC_DONEBIT(21)
+#define DESC_ATTR_REQ_STS  BIT(22) /* TX and RX before use */
+#define DESC_ATTR_RX_BUF_OVRN_ERR  BIT(22) /* RX after use */
+#define DESC_ATTR_INT_EN   BIT(23)
+#define DESC_ATTR_OFFSET_SHIFT 24
+#define DESC_ATTR_OFFSET_MASK  GENMASK(31, DESC_ATTR_OFFSET_SHIFT)
+
+
 /* NHI registers in bar 0 */
 
 /*
@@ -60,6 +92,30 @@ struct ring_desc {
  */
 #define REG_RX_RING_BASE   0x08000
 
+#define REG_RING_STEP  16
+#define REG_RING_PHYS_LO_OFFSET0
+#define REG_RING_PHYS_HI_OFFSET4
+#define REG_RING_CONS_PROD_OFFSET  8   /* cons - RO, prod - RW */
+#define REG_RING_CONS_SHIFT0
+#define REG_RING_CONS_MASK GENMASK(15, REG_RING_CONS_SHIFT)
+#define REG_RING_PROD_SHIFT16
+#define REG_RING_PROD_MASK GENMASK(31, REG_RING_PROD_SHIFT)
+#define REG_RING_SIZE_OFFSET   12
+#define REG_RING_SIZE_SHIFT0
+#define REG_RING_SIZE_MASK GENMASK(15, REG_RING_SIZE_SHIFT)
+#define REG_RING_BUF_SIZE_SHIFT16
+#define REG_RING_BUF_SIZE_MASK GENMASK(27, REG_RING_BUF_SIZE_SHIFT)
+
+#define TBT_RING_CONS_PROD_REG(iobase, ringbase, ringnumber) \
+ ((iobase) + (ringbase) + \
+ ((ringnumber) * REG_RING_STEP) + \
+ REG_RING_CONS_PROD_OFFSET)
+
+#define TBT_REG_RING_PROD_EXTRACT(val) (((val) & REG_RING_PROD_MASK) >> \
+  REG_RING_PROD_SHIFT)
+
+#define TBT_REG_RING_CONS_EXTRACT(val) (((val) & REG_RING_CONS_MASK) >> \
+  REG_RING_CONS_SHIFT)
 /*
  * 32 bytes per entry, one entry for every hop (REG_HOP_COUNT)
  * 00: enum_ring_flags
@@ -77,6 +133,19 @@ struct ring_desc {
  * ..: unknown
  */
 #define REG_RX_OPTIONS_BASE0x29800
+#define REG_RX_OPTS_TX_E2E_HOP_ID_SHIFT12
+#define REG_RX_OPTS_TX_E2E_HOP_ID_MASK \
+   GENMASK(22, REG_RX_OPTS_TX_E2E_HOP_ID_SHIFT)
+#define REG_RX_OPTS_MASK_OFFSET4
+#define REG_RX_OPTS_MASK_EOF_SHIFT 0
+#define REG_RX_OPTS_MASK_EOF_MASK  GENMASK(15, REG_RX_OPTS_MASK_EOF_SHIFT)
+#define REG_RX_OPTS_MASK_SOF_SHIFT 16
+#define REG_RX_OPTS_MASK_SOF_MASK  GENMASK(31, REG_RX_OPTS_MASK_SOF_SHIFT)
+
+#define REG_OPTS_STEP  32
+#define REG_OPTS_E2E_ENBIT(28)
+#define REG_OPTS_RAW   BIT(30)
+#define REG_OPTS_VALID BIT(31)
 
 /*
  * three bitfields: tx, rx, rx overflow
@@ -86,6 +155,7 @@ struct ring_desc {
  */
 #define REG_RING_NOTIFY_BASE   0x37800
 #define RING_NOTIFY_REG_COUNT(nhi) ((31 + 3 * nhi->hop_count) / 32)
+#define REG_RING_NOTIFY_STEP   4
 
 /*
  * two bitfields: rx, tx
@@ -94,8 +164,47 @@ struct ring_desc {
  */
 #define REG_RING_INTERRUPT_BASE0x38200
 #define RING_INTERRUPT_REG_COUNT(nhi) ((31 + 2 * nhi->hop_count) / 32)
+#define REG_RING_INT_TX_PROCESSED(ring_num)BIT(ring_num)
+#define REG_RING_INT_RX_PROCESSED(ring_num, num_paths) BIT((ring_num) + \
+   (num_paths))
+#define RING_INT_DISABLE(base, val) iowrite32( \
+   ioread32((base) + REG_RING_INTERRUPT_BASE) & ~(val), \
+   (base) + REG_RING_IN

[PATCH v8 0/8] thunderbolt: Introducing Thunderbolt(TM) Networking

2016-09-28 Thread Amir Levy
This driver enables Thunderbolt Networking on non-Apple platforms
running Linux.

Thunderbolt Networking provides peer-to-peer connections to transfer
files between computers, perform PC migrations, and/or set up small
workgroups with shared storage.

This is a virtual connection that emulates an Ethernet adapter that
enables Ethernet networking with the benefit of Thunderbolt superfast
medium capability.

Thunderbolt Networking enables two hosts and several devices that
have a Thunderbolt controller to be connected together in a linear
(Daisy chain) series from a single port.

Thunderbolt Networking for Linux is compatible with Thunderbolt
Networking on systems running macOS or Windows and also supports
Thunderbolt generation 2 and 3 controllers.

Note that all pre-existing Thunderbolt generation 3 features, such as
USB, Display and other Thunderbolt device connectivity will continue
to function exactly as they did prior to enabling Thunderbolt Networking.

Code and Software Specifications:
This kernel code creates a virtual ethernet device for computer to
computer communication over a Thunderbolt cable.
The new driver is a separate driver to the existing Thunderbolt driver.
It is designed to work on systems running Linux that
interface with Intel Connection Manager (ICM) firmware based
Thunderbolt controllers that support Thunderbolt Networking.
The kernel code operates in coordination with the Thunderbolt user-
space daemon to implement full Thunderbolt networking functionality.

Hardware Specifications:
Thunderbolt Hardware specs have not yet been published but are used
where necessary for register definitions. 

Changes since v7:
 - Removed debug prints
 - Edited error prints
 - Edited copyright notice
 - Changed the Kconfig patch to be after the code changes

These patches were pushed to GitHub where they can be reviewed more
comfortably with green/red highlighting:
https://github.com/01org/thunderbolt-software-kernel-tree

Daemon code:
https://github.com/01org/thunderbolt-software-daemon

For reference, here's a link to version 6:
[v7]:   https://lkml.org/lkml/2016/9/27/244

Amir Levy (8):
  thunderbolt: Macro rename
  thunderbolt: Updating the register definitions
  thunderbolt: Communication with the ICM (firmware)
  thunderbolt: Networking state machine
  thunderbolt: Networking transmit and receive
  thunderbolt: Kconfig for Thunderbolt Networking
  thunderbolt: Networking doc
  thunderbolt: Adding maintainer entry

 Documentation/00-INDEX   |2 +
 Documentation/thunderbolt/networking.txt |  132 ++
 MAINTAINERS  |8 +-
 drivers/thunderbolt/Kconfig  |   27 +-
 drivers/thunderbolt/Makefile |3 +-
 drivers/thunderbolt/icm/Makefile |2 +
 drivers/thunderbolt/icm/icm_nhi.c| 1514 
 drivers/thunderbolt/icm/icm_nhi.h|   82 ++
 drivers/thunderbolt/icm/net.c| 2254 ++
 drivers/thunderbolt/icm/net.h|  287 
 drivers/thunderbolt/nhi_regs.h   |  115 +-
 11 files changed, 4417 insertions(+), 9 deletions(-)
 create mode 100644 Documentation/thunderbolt/networking.txt
 create mode 100644 drivers/thunderbolt/icm/Makefile
 create mode 100644 drivers/thunderbolt/icm/icm_nhi.c
 create mode 100644 drivers/thunderbolt/icm/icm_nhi.h
 create mode 100644 drivers/thunderbolt/icm/net.c
 create mode 100644 drivers/thunderbolt/icm/net.h

-- 
2.7.4



[PATCH v7 3/8] thunderbolt: Kconfig for Thunderbolt Networking

2016-09-27 Thread Amir Levy
Update to the Kconfig Thunderbolt description to add
Thunderbolt networking as an option.
The menu item "Thunderbolt support" now offers:
"Apple Hardware Support" (existing)
and/or
"Thunderbolt Networking" (new)

You can choose the driver for your platform or build both drivers -
each driver will detect if it can run on the specific platform.
If the Thunderbolt Networking option is chosen, Thunderbolt Networking
will be enabled between Linux non-Apple systems, macOS and
Windows based systems.
Thunderbolt Networking will not affect any other Thunderbolt feature that
was previous available to Linux users on either Apple or
non-Apple platforms.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 drivers/thunderbolt/Kconfig  | 27 +++
 drivers/thunderbolt/Makefile |  2 +-
 2 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/drivers/thunderbolt/Kconfig b/drivers/thunderbolt/Kconfig
index c121acc..376e5bb 100644
--- a/drivers/thunderbolt/Kconfig
+++ b/drivers/thunderbolt/Kconfig
@@ -1,13 +1,32 @@
-menuconfig THUNDERBOLT
-   tristate "Thunderbolt support for Apple devices"
+config THUNDERBOLT
+   tristate "Thunderbolt support"
depends on PCI
select CRC32
help
- Cactus Ridge Thunderbolt Controller driver
+ Thunderbolt Controller driver
+
+if THUNDERBOLT
+
+config THUNDERBOLT_APPLE
+   tristate "Apple hardware support"
+   help
  This driver is required if you want to hotplug Thunderbolt devices on
  Apple hardware.
 
  Device chaining is currently not supported.
 
- To compile this driver a module, choose M here. The module will be
+ To compile this driver as a module, choose M here. The module will be
  called thunderbolt.
+
+config THUNDERBOLT_ICM
+   tristate "Thunderbolt Networking"
+   help
+ This driver is required if you want Thunderbolt Networking on
+ non-Apple hardware.
+ It creates a virtual Ethernet device that enables computer to
+ computer communication over a Thunderbolt cable.
+
+ To compile this driver as a module, choose M here. The module will be
+ called thunderbolt_icm.
+
+endif
diff --git a/drivers/thunderbolt/Makefile b/drivers/thunderbolt/Makefile
index 5d1053c..7a85bd1 100644
--- a/drivers/thunderbolt/Makefile
+++ b/drivers/thunderbolt/Makefile
@@ -1,3 +1,3 @@
-obj-${CONFIG_THUNDERBOLT} := thunderbolt.o
+obj-${CONFIG_THUNDERBOLT_APPLE} := thunderbolt.o
 thunderbolt-objs := nhi.o ctl.o tb.o switch.o cap.o path.o tunnel_pci.o 
eeprom.o
 
-- 
2.7.4



[PATCH v7 2/8] thunderbolt: Updating the register definitions

2016-09-27 Thread Amir Levy
Adding more Thunderbolt(TM) register definitions
and some helper macros.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 drivers/thunderbolt/nhi_regs.h | 109 +
 1 file changed, 109 insertions(+)

diff --git a/drivers/thunderbolt/nhi_regs.h b/drivers/thunderbolt/nhi_regs.h
index 75cf069..b8e961f 100644
--- a/drivers/thunderbolt/nhi_regs.h
+++ b/drivers/thunderbolt/nhi_regs.h
@@ -9,6 +9,11 @@
 
 #include 
 
+#define NHI_MMIO_BAR 0
+
+#define TBT_RING_MIN_NUM_BUFFERS   2
+#define TBT_RING_MAX_FRAME_SIZE(4 * 1024)
+
 enum ring_flags {
RING_FLAG_ISOCH_ENABLE = 1 << 27, /* TX only? */
RING_FLAG_E2E_FLOW_CONTROL = 1 << 28,
@@ -39,6 +44,33 @@ struct ring_desc {
u32 time; /* write zero */
 } __packed;
 
+/**
+ * struct tbt_buf_desc - TX/RX ring buffer descriptor.
+ * This is same as struct ring_desc, but without the use of bitfields and
+ * with explicit endianity.
+ */
+struct tbt_buf_desc {
+   __le64 phys;
+   __le32 attributes;
+   __le32 time;
+};
+
+#define DESC_ATTR_LEN_SHIFT0
+#define DESC_ATTR_LEN_MASK GENMASK(11, DESC_ATTR_LEN_SHIFT)
+#define DESC_ATTR_EOF_SHIFT12
+#define DESC_ATTR_EOF_MASK GENMASK(15, DESC_ATTR_EOF_SHIFT)
+#define DESC_ATTR_SOF_SHIFT16
+#define DESC_ATTR_SOF_MASK GENMASK(19, DESC_ATTR_SOF_SHIFT)
+#define DESC_ATTR_TX_ISOCH_DMA_EN  BIT(20) /* TX */
+#define DESC_ATTR_RX_CRC_ERR   BIT(20) /* RX after use */
+#define DESC_ATTR_DESC_DONEBIT(21)
+#define DESC_ATTR_REQ_STS  BIT(22) /* TX and RX before use */
+#define DESC_ATTR_RX_BUF_OVRN_ERR  BIT(22) /* RX after use */
+#define DESC_ATTR_INT_EN   BIT(23)
+#define DESC_ATTR_OFFSET_SHIFT 24
+#define DESC_ATTR_OFFSET_MASK  GENMASK(31, DESC_ATTR_OFFSET_SHIFT)
+
+
 /* NHI registers in bar 0 */
 
 /*
@@ -60,6 +92,30 @@ struct ring_desc {
  */
 #define REG_RX_RING_BASE   0x08000
 
+#define REG_RING_STEP  16
+#define REG_RING_PHYS_LO_OFFSET0
+#define REG_RING_PHYS_HI_OFFSET4
+#define REG_RING_CONS_PROD_OFFSET  8   /* cons - RO, prod - RW */
+#define REG_RING_CONS_SHIFT0
+#define REG_RING_CONS_MASK GENMASK(15, REG_RING_CONS_SHIFT)
+#define REG_RING_PROD_SHIFT16
+#define REG_RING_PROD_MASK GENMASK(31, REG_RING_PROD_SHIFT)
+#define REG_RING_SIZE_OFFSET   12
+#define REG_RING_SIZE_SHIFT0
+#define REG_RING_SIZE_MASK GENMASK(15, REG_RING_SIZE_SHIFT)
+#define REG_RING_BUF_SIZE_SHIFT16
+#define REG_RING_BUF_SIZE_MASK GENMASK(27, REG_RING_BUF_SIZE_SHIFT)
+
+#define TBT_RING_CONS_PROD_REG(iobase, ringbase, ringnumber) \
+ ((iobase) + (ringbase) + \
+ ((ringnumber) * REG_RING_STEP) + \
+ REG_RING_CONS_PROD_OFFSET)
+
+#define TBT_REG_RING_PROD_EXTRACT(val) (((val) & REG_RING_PROD_MASK) >> \
+  REG_RING_PROD_SHIFT)
+
+#define TBT_REG_RING_CONS_EXTRACT(val) (((val) & REG_RING_CONS_MASK) >> \
+  REG_RING_CONS_SHIFT)
 /*
  * 32 bytes per entry, one entry for every hop (REG_HOP_COUNT)
  * 00: enum_ring_flags
@@ -77,6 +133,19 @@ struct ring_desc {
  * ..: unknown
  */
 #define REG_RX_OPTIONS_BASE0x29800
+#define REG_RX_OPTS_TX_E2E_HOP_ID_SHIFT12
+#define REG_RX_OPTS_TX_E2E_HOP_ID_MASK \
+   GENMASK(22, REG_RX_OPTS_TX_E2E_HOP_ID_SHIFT)
+#define REG_RX_OPTS_MASK_OFFSET4
+#define REG_RX_OPTS_MASK_EOF_SHIFT 0
+#define REG_RX_OPTS_MASK_EOF_MASK  GENMASK(15, REG_RX_OPTS_MASK_EOF_SHIFT)
+#define REG_RX_OPTS_MASK_SOF_SHIFT 16
+#define REG_RX_OPTS_MASK_SOF_MASK  GENMASK(31, REG_RX_OPTS_MASK_SOF_SHIFT)
+
+#define REG_OPTS_STEP  32
+#define REG_OPTS_E2E_ENBIT(28)
+#define REG_OPTS_RAW   BIT(30)
+#define REG_OPTS_VALID BIT(31)
 
 /*
  * three bitfields: tx, rx, rx overflow
@@ -86,6 +155,7 @@ struct ring_desc {
  */
 #define REG_RING_NOTIFY_BASE   0x37800
 #define RING_NOTIFY_REG_COUNT(nhi) ((31 + 3 * nhi->hop_count) / 32)
+#define REG_RING_NOTIFY_STEP   4
 
 /*
  * two bitfields: rx, tx
@@ -94,8 +164,47 @@ struct ring_desc {
  */
 #define REG_RING_INTERRUPT_BASE0x38200
 #define RING_INTERRUPT_REG_COUNT(nhi) ((31 + 2 * nhi->hop_count) / 32)
+#define REG_RING_INT_TX_PROCESSED(ring_num)BIT(ring_num)
+#define REG_RING_INT_RX_PROCESSED(ring_num, num_paths) BIT((ring_num) + \
+   (num_paths))
+#define RING_INT_DISABLE(base, val) iowrite32( \
+   ioread32((base) + REG_RING_INTERRUPT_BASE) & ~(val), \
+   (base) + REG_RING_IN

[PATCH v7 4/8] thunderbolt: Communication with the ICM (firmware)

2016-09-27 Thread Amir Levy
This patch provides the communication protocol between the
Intel Connection Manager(ICM) firmware that is operational in the
Thunderbolt controller in non-Apple hardware.
The ICM firmware-based controller is used for establishing and maintaining
the Thunderbolt Networking connection - we need to be able to communicate
with it.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 drivers/thunderbolt/Makefile  |1 +
 drivers/thunderbolt/icm/Makefile  |2 +
 drivers/thunderbolt/icm/icm_nhi.c | 1324 +
 drivers/thunderbolt/icm/icm_nhi.h |   92 +++
 drivers/thunderbolt/icm/net.h |  227 +++
 5 files changed, 1646 insertions(+)
 create mode 100644 drivers/thunderbolt/icm/Makefile
 create mode 100644 drivers/thunderbolt/icm/icm_nhi.c
 create mode 100644 drivers/thunderbolt/icm/icm_nhi.h
 create mode 100644 drivers/thunderbolt/icm/net.h

diff --git a/drivers/thunderbolt/Makefile b/drivers/thunderbolt/Makefile
index 7a85bd1..b6aa6a3 100644
--- a/drivers/thunderbolt/Makefile
+++ b/drivers/thunderbolt/Makefile
@@ -1,3 +1,4 @@
 obj-${CONFIG_THUNDERBOLT_APPLE} := thunderbolt.o
 thunderbolt-objs := nhi.o ctl.o tb.o switch.o cap.o path.o tunnel_pci.o 
eeprom.o
 
+obj-${CONFIG_THUNDERBOLT_ICM} += icm/
diff --git a/drivers/thunderbolt/icm/Makefile b/drivers/thunderbolt/icm/Makefile
new file mode 100644
index 000..f0d0fbb
--- /dev/null
+++ b/drivers/thunderbolt/icm/Makefile
@@ -0,0 +1,2 @@
+obj-${CONFIG_THUNDERBOLT_ICM} += thunderbolt-icm.o
+thunderbolt-icm-objs := icm_nhi.o
diff --git a/drivers/thunderbolt/icm/icm_nhi.c 
b/drivers/thunderbolt/icm/icm_nhi.c
new file mode 100644
index 000..984aa7c
--- /dev/null
+++ b/drivers/thunderbolt/icm/icm_nhi.c
@@ -0,0 +1,1324 @@
+/***
+ *
+ * Intel Thunderbolt(TM) driver
+ * Copyright(c) 2014 - 2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Intel Thunderbolt Mailing List <thunderbolt-softw...@lists.01.org>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ 
**/
+
+#include 
+#include 
+#include 
+#include 
+#include "icm_nhi.h"
+#include "net.h"
+
+#define NHI_GENL_VERSION 1
+#define NHI_GENL_NAME "thunderbolt"
+
+#define DEVICE_DATA(num_ports, dma_port, nvm_ver_offset, nvm_auth_on_boot,\
+   support_full_e2e) \
+   ((num_ports) | ((dma_port) << 4) | ((nvm_ver_offset) << 10) | \
+((nvm_auth_on_boot) << 22) | ((support_full_e2e) << 23))
+#define DEVICE_DATA_NUM_PORTS(device_data) ((device_data) & 0xf)
+#define DEVICE_DATA_DMA_PORT(device_data) (((device_data) >> 4) & 0x3f)
+#define DEVICE_DATA_NVM_VER_OFFSET(device_data) (((device_data) >> 10) & 0xfff)
+#define DEVICE_DATA_NVM_AUTH_ON_BOOT(device_data) (((device_data) >> 22) & 0x1)
+#define DEVICE_DATA_SUPPORT_FULL_E2E(device_data) (((device_data) >> 23) & 0x1)
+
+#define USEC_TO_256_NSECS(usec) DIV_ROUND_UP((usec) * NSEC_PER_USEC, 256)
+
+/* NHI genetlink commands */
+enum {
+   NHI_CMD_UNSPEC,
+   NHI_CMD_SUBSCRIBE,
+   NHI_CMD_UNSUBSCRIBE,
+   NHI_CMD_QUERY_INFORMATION,
+   NHI_CMD_MSG_TO_ICM,
+   NHI_CMD_MSG_FROM_ICM,
+   NHI_CMD_MAILBOX,
+   NHI_CMD_APPROVE_TBT_NETWORKING,
+   NHI_CMD_ICM_IN_SAFE_MODE,
+   __NHI_CMD_MAX,
+};
+#define NHI_CMD_MAX (__NHI_CMD_MAX - 1)
+
+/* NHI genetlink policy */
+static const struct nla_policy nhi_genl_policy[NHI_ATTR_MAX + 1] = {
+   [NHI_ATTR_DRV_VERSION]  = { .type = NLA_NUL_STRING, },
+   [NHI_ATTR_NVM_VER_OFFSET]   = { .type = NLA_U16, },
+   [NHI_ATTR_NUM_PORTS]= { .type = NLA_U8, },
+   [NHI_ATTR_DMA_PORT] = { .type = NLA_U8, },
+   [NHI_ATTR_SUPPORT_FULL_E2E] = { .type = NLA_FLAG, },
+   [NHI_ATTR_MAILBOX_CMD]  = { .type = NLA_U32, },
+   [NHI_ATTR_PDF]  = { .type = NLA_U32, },
+   [NHI_ATTR_MSG_TO_ICM]   = { .type = NLA_BINARY,
+   .len = TBT_ICM_RING_MAX_FRAME_SIZE },
+   [NHI_ATTR_MSG_FROM_IC

[PATCH v7 1/8] thunderbolt: Macro rename

2016-09-27 Thread Amir Levy
This first patch updates the NHI Thunderbolt controller registers file to
reflect that it is not only for Cactus Ridge.
No functional change intended.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
Signed-off-by: Andreas Noever <andreas.noe...@gmail.com>
---
 drivers/thunderbolt/nhi_regs.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/thunderbolt/nhi_regs.h b/drivers/thunderbolt/nhi_regs.h
index 86b996c..75cf069 100644
--- a/drivers/thunderbolt/nhi_regs.h
+++ b/drivers/thunderbolt/nhi_regs.h
@@ -1,11 +1,11 @@
 /*
- * Thunderbolt Cactus Ridge driver - NHI registers
+ * Thunderbolt driver - NHI registers
  *
  * Copyright (c) 2014 Andreas Noever <andreas.noe...@gmail.com>
  */
 
-#ifndef DSL3510_REGS_H_
-#define DSL3510_REGS_H_
+#ifndef NHI_REGS_H_
+#define NHI_REGS_H_
 
 #include 
 
-- 
2.7.4



[PATCH v7 0/8] thunderbolt: Introducing Thunderbolt(TM) Networking

2016-09-27 Thread Amir Levy
This driver enables Thunderbolt Networking on non-Apple platforms
running Linux.

Thunderbolt Networking provides peer-to-peer connections to transfer
files between computers, perform PC migrations, and/or set up small
workgroups with shared storage.

This is a virtual connection that emulates an Ethernet adapter that
enables Ethernet networking with the benefit of Thunderbolt superfast
medium capability.

Thunderbolt Networking enables two hosts and several devices that
have a Thunderbolt controller to be connected together in a linear
(Daisy chain) series from a single port.

Thunderbolt Networking for Linux is compatible with Thunderbolt
Networking on systems running macOS or Windows and also supports
Thunderbolt generation 2 and 3 controllers.

Note that all pre-existing Thunderbolt generation 3 features, such as
USB, Display and other Thunderbolt device connectivity will continue
to function exactly as they did prior to enabling Thunderbolt Networking.

Code and Software Specifications:
This kernel code creates a virtual ethernet device for computer to
computer communication over a Thunderbolt cable.
The new driver is a separate driver to the existing Thunderbolt driver.
It is designed to work on systems running Linux that
interface with Intel Connection Manager (ICM) firmware based
Thunderbolt controllers that support Thunderbolt Networking.
The kernel code operates in coordination with the Thunderbolt user-
space daemon to implement full Thunderbolt networking functionality.

Hardware Specifications:
Thunderbolt Hardware specs have not yet been published but are used
where necessary for register definitions. 

Changes since v6:
 - Removed (TM) from Kconfig
 - Removed redundant DRV_NAME macro
 - Removed copyright notice from Makefile
 - Moved networking.txt file to Documentation/Thunderbolt/
 - Edited patch descriptions
 - Edited documentation in networking.txt

These patches were pushed to GitHub where they can be reviewed more
comfortably with green/red highlighting:
https://github.com/01org/thunderbolt-software-kernel-tree

Daemon code:
https://github.com/01org/thunderbolt-software-daemon

For reference, here's a link to version 6:
[v6]:   https://lkml.org/lkml/2016/8/1/233

Amir Levy (8):
  thunderbolt: Macro rename
  thunderbolt: Updating the register definitions
  thunderbolt: Kconfig for Thunderbolt Networking
  thunderbolt: Communication with the ICM (firmware)
  thunderbolt: Networking state machine
  thunderbolt: Networking transmit and receive
  thunderbolt: Networking doc
  thunderbolt: Adding maintainer entry

 Documentation/00-INDEX   |2 +
 Documentation/thunderbolt/networking.txt |  132 ++
 MAINTAINERS  |8 +-
 drivers/thunderbolt/Kconfig  |   27 +-
 drivers/thunderbolt/Makefile |3 +-
 drivers/thunderbolt/icm/Makefile |2 +
 drivers/thunderbolt/icm/icm_nhi.c| 1622 +
 drivers/thunderbolt/icm/icm_nhi.h|   92 ++
 drivers/thunderbolt/icm/net.c| 2264 ++
 drivers/thunderbolt/icm/net.h|  297 
 drivers/thunderbolt/nhi_regs.h   |  115 +-
 11 files changed, 4555 insertions(+), 9 deletions(-)
 create mode 100644 Documentation/thunderbolt/networking.txt
 create mode 100644 drivers/thunderbolt/icm/Makefile
 create mode 100644 drivers/thunderbolt/icm/icm_nhi.c
 create mode 100644 drivers/thunderbolt/icm/icm_nhi.h
 create mode 100644 drivers/thunderbolt/icm/net.c
 create mode 100644 drivers/thunderbolt/icm/net.h

-- 
2.7.4



[PATCH v7 8/8] thunderbolt: Adding maintainer entry

2016-09-27 Thread Amir Levy
Add Amir Levy as maintainer for Thunderbolt(TM) ICM driver

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 MAINTAINERS | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 01bff8e..a4a4614 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10358,7 +10358,13 @@ F: include/uapi/linux/stm.h
 THUNDERBOLT DRIVER
 M: Andreas Noever <andreas.noe...@gmail.com>
 S: Maintained
-F: drivers/thunderbolt/
+F: drivers/thunderbolt/*
+
+THUNDERBOLT ICM DRIVER
+M:     Amir Levy <amir.jer.l...@intel.com>
+S: Maintained
+F: drivers/thunderbolt/icm/
+F: Documentation/thunderbolt/networking.txt
 
 TI BQ27XXX POWER SUPPLY DRIVER
 R: Andrew F. Davis <a...@ti.com>
-- 
2.7.4



[PATCH v7 5/8] thunderbolt: Networking state machine

2016-09-27 Thread Amir Levy
This patch builds the peer to peer communication path.
Communication is established by a negotiation process whereby messages are
sent back and forth between the peers until a connection is established.
This includes the Thunderbolt Network driver communication with the second
peer via Intel Connection Manager(ICM) firmware.
  ++++
  |Host 1  ||Host 2  |
  ||||
  | +---+  || +---+  |
  | |Thunderbolt|  || |Thunderbolt|  |
  | |Networking |  || |Networking |  |
  | |Driver |  || |Driver |  |
  | +---+  || +---+  |
  |  ^ ||  ^ |
  |  | ||  | |
  | ++---+ || ++---+ |
  | |Thunderbolt |   | || |Thunderbolt |   | |
  | |Controller  v   | || |Controller  v   | |
  | | +---+  | || | +---+  | |
  | | |ICM|<-+-++-+>|ICM|  | |
  | | +---+  | || | +---+  | |
  | ++ || ++ |
  ++++
Note that this patch only establishes the link between the two hosts and
not Network Packet handling - this is dealt with in the next patch.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 drivers/thunderbolt/icm/Makefile  |   2 +-
 drivers/thunderbolt/icm/icm_nhi.c | 303 ++-
 drivers/thunderbolt/icm/net.c | 793 ++
 drivers/thunderbolt/icm/net.h |  70 
 4 files changed, 1157 insertions(+), 11 deletions(-)
 create mode 100644 drivers/thunderbolt/icm/net.c

diff --git a/drivers/thunderbolt/icm/Makefile b/drivers/thunderbolt/icm/Makefile
index f0d0fbb..94a2797 100644
--- a/drivers/thunderbolt/icm/Makefile
+++ b/drivers/thunderbolt/icm/Makefile
@@ -1,2 +1,2 @@
 obj-${CONFIG_THUNDERBOLT_ICM} += thunderbolt-icm.o
-thunderbolt-icm-objs := icm_nhi.o
+thunderbolt-icm-objs := icm_nhi.o net.o
diff --git a/drivers/thunderbolt/icm/icm_nhi.c 
b/drivers/thunderbolt/icm/icm_nhi.c
index 984aa7c..578eb14 100644
--- a/drivers/thunderbolt/icm/icm_nhi.c
+++ b/drivers/thunderbolt/icm/icm_nhi.c
@@ -74,6 +74,12 @@ static const struct nla_policy nhi_genl_policy[NHI_ATTR_MAX 
+ 1] = {
.len = TBT_ICM_RING_MAX_FRAME_SIZE },
[NHI_ATTR_MSG_FROM_ICM] = { .type = NLA_BINARY,
.len = TBT_ICM_RING_MAX_FRAME_SIZE },
+   [NHI_ATTR_LOCAL_ROUTE_STRING]   = {.len = sizeof(struct route_string)},
+   [NHI_ATTR_LOCAL_UUID]   = { .len = sizeof(uuid_be) },
+   [NHI_ATTR_REMOTE_UUID]  = { .len = sizeof(uuid_be) },
+   [NHI_ATTR_LOCAL_DEPTH]  = { .type = NLA_U8, },
+   [NHI_ATTR_ENABLE_FULL_E2E]  = { .type = NLA_FLAG, },
+   [NHI_ATTR_MATCH_FRAME_ID]   = { .type = NLA_FLAG, },
 };
 
 /* NHI genetlink family */
@@ -522,6 +528,29 @@ int nhi_mailbox(struct tbt_nhi_ctxt *nhi_ctxt, u32 cmd, 
u32 data, bool deinit)
return 0;
 }
 
+static inline bool nhi_is_path_disconnected(u32 cmd, u8 num_ports)
+{
+   return (cmd >= DISCONNECT_PORT_A_INTER_DOMAIN_PATH &&
+   cmd < (DISCONNECT_PORT_A_INTER_DOMAIN_PATH + num_ports));
+}
+
+static int nhi_mailbox_disconn_path(struct tbt_nhi_ctxt *nhi_ctxt, u32 cmd)
+   __releases(_list_mutex)
+{
+   struct port_net_dev *port;
+   u32 port_num = cmd - DISCONNECT_PORT_A_INTER_DOMAIN_PATH;
+
+   port = &(nhi_ctxt->net_devices[port_num]);
+   mutex_lock(>state_mutex);
+
+   mutex_unlock(_list_mutex);
+   port->medium_sts = MEDIUM_READY_FOR_APPROVAL;
+   if (port->net_dev)
+   negotiation_events(port->net_dev, MEDIUM_DISCONNECTED);
+   mutex_unlock(>state_mutex);
+   return  0;
+}
+
 static int nhi_mailbox_generic(struct tbt_nhi_ctxt *nhi_ctxt, u32 mb_cmd)
__releases(_list_mutex)
 {
@@ -571,13 +600,94 @@ static int nhi_genl_mailbox(__always_unused struct 
sk_buff *u_skb,
return -ERESTART;
 
nhi_ctxt = nhi_search_ctxt(*(u32 *)info->userhdr);
-   if (nhi_ctxt && !nhi_ctxt->d0_exit)
-   return nhi_mailbox_generic(nhi_ctxt, mb_cmd);
+   if (nhi_ctxt && !nhi_ctxt->d0_exit) {
+
+   /* rwsem is released later by the below functions */
+   if (nhi_is_path_disconnected(cmd, nhi_ctxt->num_ports))
+   return nhi_mailbox_disconn_path(nhi_ctxt, cmd);
+   else
+   return nhi_mailbox_generic(nhi_ctxt, mb_cmd);
+
+   }
 
mutex_unlock(_list_mutex);
return -ENODEV;
 }
 
+

[PATCH v7 7/8] thunderbolt: Networking doc

2016-09-27 Thread Amir Levy
Adding Thunderbolt(TM) networking documentation.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 Documentation/00-INDEX   |   2 +
 Documentation/thunderbolt/networking.txt | 132 +++
 2 files changed, 134 insertions(+)
 create mode 100644 Documentation/thunderbolt/networking.txt

diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX
index cb9a6c6..a448ba1 100644
--- a/Documentation/00-INDEX
+++ b/Documentation/00-INDEX
@@ -439,6 +439,8 @@ this_cpu_ops.txt
- List rationale behind and the way to use this_cpu operations.
 thermal/
- directory with information on managing thermal issues (CPU/temp)
+thunderbolt/
+   - directory with info regarding Thunderbolt.
 trace/
- directory with info on tracing technologies within linux
 unaligned-memory-access.txt
diff --git a/Documentation/thunderbolt/networking.txt 
b/Documentation/thunderbolt/networking.txt
new file mode 100644
index 000..88d1c12
--- /dev/null
+++ b/Documentation/thunderbolt/networking.txt
@@ -0,0 +1,132 @@
+Intel Thunderbolt(TM) Networking driver
+===
+
+Copyright(c) 2013 - 2016 Intel Corporation.
+
+Contact Information:
+Intel Thunderbolt mailing list <thunderbolt-softw...@lists.01.org>
+Edited by Amir Levy <amir.jer.l...@intel.com>
+
+Overview
+
+
+* The Thunderbolt Networking driver enables peer to peer networking on 
non-Apple
+  platforms running Linux.
+
+* The driver creates a virtual Ethernet device that enables computer to 
computer
+  communication over the Thunderbolt cable.
+
+* Using Thunderbolt Networking you can perform high speed file transfers 
between
+  computers, perform PC migrations and/or set up small workgroups with shared
+  storage without compromising any other Thunderbolt functionality.
+
+* The driver is located in drivers/thunderbolt/icm.
+
+* This driver will function only on non-Apple platforms with firmware based
+  Thunderbolt controllers that support Thunderbolt Networking.
+
+  ++++
+  |Host 1  ||Host 2  |
+  ||||
+  |   +---+||+---+   |
+  |   |Network||||Network|   |
+  |   |Stack  ||||Stack  |   |
+  |   +---+||+---+   |
+  |   ^||^   |
+  |   ||||   |
+  |   v||v   |
+  | +---+  ||  +---+ |
+  | |Thunderbolt|  ||  |Thunderbolt| |
+  | |Networking |  ||  |Networking | |
+  | |Driver |  ||  |Driver | |
+  | +---+  ||  +---+ |
+  |   ^||^   |
+  |   ||||   |
+  |   v||v   |
+  | +---+  ||  +---+ |
+  | |Thunderbolt|  ||  |Thunderbolt| |
+  | |Controller |<-++->|Controller | |
+  | |with ICM   |  ||  |with ICM   | |
+  | |enabled|  ||  |enabled| |
+  | +---+  ||  +---+ |
+  ++++
+
+Files
+=
+
+The following files are located in the drivers/thunderbolt/icm directory:
+
+- icm_nhi.c/h: These files allow communication with the firmware (Intel
+  Connection Manager) based controller. They also create an interface for
+  netlink communication with a user space daemon.
+
+- net.c/net.h: These files implement the 'eth' interface for the
+  Thunderbolt(TM) Networking.
+
+Interface to User Space
+===
+
+The interface to the user space module is implemented through a Generic 
Netlink.
+This is the communications protocol between the Thunderbolt driver and the user
+space application.
+
+Note that this interface mediates user space communication with ICM.
+(Existing Linux tools can be used to configure the network interface.)
+
+The Thunderbolt Daemon utilizes this interface to communicate with the driver.
+To be accessed by the user space module, both kernel and user space modules
+have to register with the same GENL_NAME.
+For the purpose of the Thunderbolt Network driver, "thunderbolt" is used.
+The registration is done at driver initialization time for all instances
+of the Thunderbolt controllers. The communication is carried through 
pre-defined
+Thunderbolt messages. Each specific message has a callback function that is
+called when the related message is received.
+
+Message Definitions:
+* NHI_CMD_UNSPEC: Not used.
+* NHI_CMD_SUBSCRIBE: Subscription request from daemon to driver to open the
+  communication channel.
+* NHI_CMD_UNSUBSCRIBE: Request from daemon to driver to unsubscribe and
+  to close communication channel.
+* NHI_CMD_QUERY_INFORMATION: R

[PATCH v7 6/8] thunderbolt: Networking transmit and receive

2016-09-27 Thread Amir Levy
This patch provides the handling interface for sending and receiving
network packets between the hosts over the full communication route
(using the communication path established in the previous patch).

The Thunderbolt Network driver interfaces the Linux network stack
and the hardware controller configuration to handle packet transmissions:
  ++++
  |Host 1  ||Host 2  |
  ||||
  |   +---+||+---+   |
  |   |Network||||Network|   |
  |   |Stack  ||||Stack  |   |
  |   +---+||+---+   |
  |   ^||^   |
  |   ||||   |
  |   v||v   |
  | +---+  ||  +---+ |
  | |Thunderbolt|  ||  |Thunderbolt| |
  | |Networking |  ||  |Networking | |
  | |Driver |  ||  |Driver | |
  | +---+  ||  +---+ |
  |   ^||^   |
  |   ||||   |
  |   v||v   |
  | +---+  ||  +---+ |
  | |Thunderbolt|  ||  |Thunderbolt| |
  | |Controller |<-++->|Controller | |
  | +---+  ||  +---+ |
  ++++

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 drivers/thunderbolt/icm/icm_nhi.c |   15 +
 drivers/thunderbolt/icm/net.c | 1471 +
 2 files changed, 1486 insertions(+)

diff --git a/drivers/thunderbolt/icm/icm_nhi.c 
b/drivers/thunderbolt/icm/icm_nhi.c
index 578eb14..c181abf 100644
--- a/drivers/thunderbolt/icm/icm_nhi.c
+++ b/drivers/thunderbolt/icm/icm_nhi.c
@@ -1036,6 +1036,7 @@ static irqreturn_t nhi_msi(int __always_unused irq, void 
*data)
 {
struct tbt_nhi_ctxt *nhi_ctxt = data;
u32 isr0, isr1, imr0, imr1;
+   int i;
 
/* clear on read */
isr0 = ioread32(nhi_ctxt->iobase + REG_RING_NOTIFY_BASE);
@@ -1058,6 +1059,20 @@ static irqreturn_t nhi_msi(int __always_unused irq, void 
*data)
 
spin_unlock(_ctxt->lock);
 
+   for (i = 0; i < nhi_ctxt->num_ports; ++i) {
+   struct net_device *net_dev =
+   nhi_ctxt->net_devices[i].net_dev;
+   if (net_dev) {
+   u8 path = PATH_FROM_PORT(nhi_ctxt->num_paths, i);
+
+   if (isr0 & REG_RING_INT_RX_PROCESSED(
+   path, nhi_ctxt->num_paths))
+   tbt_net_rx_msi(net_dev);
+   if (isr0 & REG_RING_INT_TX_PROCESSED(path))
+   tbt_net_tx_msi(net_dev);
+   }
+   }
+
if (isr0 & REG_RING_INT_RX_PROCESSED(TBT_ICM_RING_NUM,
 nhi_ctxt->num_paths))
schedule_work(_ctxt->icm_msgs_work);
diff --git a/drivers/thunderbolt/icm/net.c b/drivers/thunderbolt/icm/net.c
index acf30ad..a0f3c4a 100644
--- a/drivers/thunderbolt/icm/net.c
+++ b/drivers/thunderbolt/icm/net.c
@@ -134,6 +134,17 @@ struct approve_inter_domain_connection_cmd {
 
 };
 
+struct tbt_frame_header {
+   /* size of the data with the frame */
+   __le32 frame_size;
+   /* running index on the frames */
+   __le16 frame_index;
+   /* ID of the frame to match frames to specific packet */
+   __le16 frame_id;
+   /* how many frames assembles a full packet */
+   __le32 frame_count;
+};
+
 enum neg_event {
RECEIVE_LOGOUT = NUM_MEDIUM_STATUSES,
RECEIVE_LOGIN_RESPONSE,
@@ -141,15 +152,81 @@ enum neg_event {
NUM_NEG_EVENTS
 };
 
+enum frame_status {
+   GOOD_FRAME,
+   GOOD_AS_FIRST_FRAME,
+   GOOD_AS_FIRST_MULTICAST_FRAME,
+   FRAME_NOT_READY,
+   FRAME_ERROR,
+};
+
+enum packet_filter {
+   /* all multicast MAC addresses */
+   PACKET_TYPE_ALL_MULTICAST,
+   /* all types of MAC addresses: multicast, unicast and broadcast */
+   PACKET_TYPE_PROMISCUOUS,
+   /* all unicast MAC addresses */
+   PACKET_TYPE_UNICAST_PROMISCUOUS,
+};
+
 enum disconnect_path_stage {
STAGE_1 = BIT(0),
STAGE_2 = BIT(1)
 };
 
+struct tbt_net_stats {
+   u64 tx_packets;
+   u64 tx_bytes;
+   u64 tx_errors;
+   u64 rx_packets;
+   u64 rx_bytes;
+   u64 rx_length_errors;
+   u64 rx_over_errors;
+   u64 rx_crc_errors;
+   u64 rx_missed_errors;
+   u64 multicast;
+};
+
+static const char tbt_net_gstrings_stats[][ETH_GSTRING_LEN] = {
+   "tx_packets",
+   "tx_bytes",
+   "tx_errors",
+   "rx_packets",
+   "rx_bytes",
+  

[PATCH v6 8/8] thunderbolt: Adding maintainer entry

2016-08-01 Thread Amir Levy
Add Amir Levy as maintainer for Thunderbolt(TM) ICM driver

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 MAINTAINERS | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 72f7703..2b6d635 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10193,7 +10193,13 @@ F: include/uapi/linux/stm.h
 THUNDERBOLT DRIVER
 M: Andreas Noever <andreas.noe...@gmail.com>
 S: Maintained
-F: drivers/thunderbolt/
+F: drivers/thunderbolt/*
+
+THUNDERBOLT ICM DRIVER
+M:     Amir Levy <amir.jer.l...@intel.com>
+S: Maintained
+F: drivers/thunderbolt/icm/
+F: Documentation/thunderbolt-networking.txt
 
 TI BQ27XXX POWER SUPPLY DRIVER
 R: Andrew F. Davis <a...@ti.com>
-- 
2.7.4



[PATCH v6 3/8] thunderbolt: Kconfig for Thunderbolt(TM) networking

2016-08-01 Thread Amir Levy
Updating the Kconfig Thunderbolt(TM) description.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 drivers/thunderbolt/Kconfig  | 25 +
 drivers/thunderbolt/Makefile |  2 +-
 2 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/drivers/thunderbolt/Kconfig b/drivers/thunderbolt/Kconfig
index c121acc..d34b0f5 100644
--- a/drivers/thunderbolt/Kconfig
+++ b/drivers/thunderbolt/Kconfig
@@ -1,13 +1,30 @@
-menuconfig THUNDERBOLT
-   tristate "Thunderbolt support for Apple devices"
+config THUNDERBOLT
+   tristate "Thunderbolt(TM) support"
depends on PCI
select CRC32
help
- Cactus Ridge Thunderbolt Controller driver
+ Thunderbolt(TM) Controller driver
+
+if THUNDERBOLT
+
+config THUNDERBOLT_APPLE
+   tristate "Apple hardware support"
+   help
  This driver is required if you want to hotplug Thunderbolt devices on
  Apple hardware.
 
  Device chaining is currently not supported.
 
- To compile this driver a module, choose M here. The module will be
+ To compile this driver as a module, choose M here. The module will be
  called thunderbolt.
+
+config THUNDERBOLT_ICM
+   tristate "Thunderbolt(TM) Networking"
+   help
+ This driver is required if you want Thunderbolt(TM) Networking on
+ non-Apple hardware.
+
+ To compile this driver as a module, choose M here. The module will be
+ called thunderbolt_icm.
+
+endif
diff --git a/drivers/thunderbolt/Makefile b/drivers/thunderbolt/Makefile
index 5d1053c..7a85bd1 100644
--- a/drivers/thunderbolt/Makefile
+++ b/drivers/thunderbolt/Makefile
@@ -1,3 +1,3 @@
-obj-${CONFIG_THUNDERBOLT} := thunderbolt.o
+obj-${CONFIG_THUNDERBOLT_APPLE} := thunderbolt.o
 thunderbolt-objs := nhi.o ctl.o tb.o switch.o cap.o path.o tunnel_pci.o 
eeprom.o
 
-- 
2.7.4



[PATCH v6 1/8] thunderbolt: Macro rename

2016-08-01 Thread Amir Levy
This first patch updates the registers file to
reflect that it isn't only for Cactus Ridge.
No functional change intended.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 drivers/thunderbolt/nhi_regs.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/thunderbolt/nhi_regs.h b/drivers/thunderbolt/nhi_regs.h
index 86b996c..75cf069 100644
--- a/drivers/thunderbolt/nhi_regs.h
+++ b/drivers/thunderbolt/nhi_regs.h
@@ -1,11 +1,11 @@
 /*
- * Thunderbolt Cactus Ridge driver - NHI registers
+ * Thunderbolt driver - NHI registers
  *
  * Copyright (c) 2014 Andreas Noever <andreas.noe...@gmail.com>
  */
 
-#ifndef DSL3510_REGS_H_
-#define DSL3510_REGS_H_
+#ifndef NHI_REGS_H_
+#define NHI_REGS_H_
 
 #include 
 
-- 
2.7.4



[PATCH v6 2/8] thunderbolt: Updating the register definitions

2016-08-01 Thread Amir Levy
Adding more Thunderbolt(TM) register definitions
and some helper macros.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 drivers/thunderbolt/nhi_regs.h | 109 +
 1 file changed, 109 insertions(+)

diff --git a/drivers/thunderbolt/nhi_regs.h b/drivers/thunderbolt/nhi_regs.h
index 75cf069..b8e961f 100644
--- a/drivers/thunderbolt/nhi_regs.h
+++ b/drivers/thunderbolt/nhi_regs.h
@@ -9,6 +9,11 @@
 
 #include 
 
+#define NHI_MMIO_BAR 0
+
+#define TBT_RING_MIN_NUM_BUFFERS   2
+#define TBT_RING_MAX_FRAME_SIZE(4 * 1024)
+
 enum ring_flags {
RING_FLAG_ISOCH_ENABLE = 1 << 27, /* TX only? */
RING_FLAG_E2E_FLOW_CONTROL = 1 << 28,
@@ -39,6 +44,33 @@ struct ring_desc {
u32 time; /* write zero */
 } __packed;
 
+/**
+ * struct tbt_buf_desc - TX/RX ring buffer descriptor.
+ * This is same as struct ring_desc, but without the use of bitfields and
+ * with explicit endianity.
+ */
+struct tbt_buf_desc {
+   __le64 phys;
+   __le32 attributes;
+   __le32 time;
+};
+
+#define DESC_ATTR_LEN_SHIFT0
+#define DESC_ATTR_LEN_MASK GENMASK(11, DESC_ATTR_LEN_SHIFT)
+#define DESC_ATTR_EOF_SHIFT12
+#define DESC_ATTR_EOF_MASK GENMASK(15, DESC_ATTR_EOF_SHIFT)
+#define DESC_ATTR_SOF_SHIFT16
+#define DESC_ATTR_SOF_MASK GENMASK(19, DESC_ATTR_SOF_SHIFT)
+#define DESC_ATTR_TX_ISOCH_DMA_EN  BIT(20) /* TX */
+#define DESC_ATTR_RX_CRC_ERR   BIT(20) /* RX after use */
+#define DESC_ATTR_DESC_DONEBIT(21)
+#define DESC_ATTR_REQ_STS  BIT(22) /* TX and RX before use */
+#define DESC_ATTR_RX_BUF_OVRN_ERR  BIT(22) /* RX after use */
+#define DESC_ATTR_INT_EN   BIT(23)
+#define DESC_ATTR_OFFSET_SHIFT 24
+#define DESC_ATTR_OFFSET_MASK  GENMASK(31, DESC_ATTR_OFFSET_SHIFT)
+
+
 /* NHI registers in bar 0 */
 
 /*
@@ -60,6 +92,30 @@ struct ring_desc {
  */
 #define REG_RX_RING_BASE   0x08000
 
+#define REG_RING_STEP  16
+#define REG_RING_PHYS_LO_OFFSET0
+#define REG_RING_PHYS_HI_OFFSET4
+#define REG_RING_CONS_PROD_OFFSET  8   /* cons - RO, prod - RW */
+#define REG_RING_CONS_SHIFT0
+#define REG_RING_CONS_MASK GENMASK(15, REG_RING_CONS_SHIFT)
+#define REG_RING_PROD_SHIFT16
+#define REG_RING_PROD_MASK GENMASK(31, REG_RING_PROD_SHIFT)
+#define REG_RING_SIZE_OFFSET   12
+#define REG_RING_SIZE_SHIFT0
+#define REG_RING_SIZE_MASK GENMASK(15, REG_RING_SIZE_SHIFT)
+#define REG_RING_BUF_SIZE_SHIFT16
+#define REG_RING_BUF_SIZE_MASK GENMASK(27, REG_RING_BUF_SIZE_SHIFT)
+
+#define TBT_RING_CONS_PROD_REG(iobase, ringbase, ringnumber) \
+ ((iobase) + (ringbase) + \
+ ((ringnumber) * REG_RING_STEP) + \
+ REG_RING_CONS_PROD_OFFSET)
+
+#define TBT_REG_RING_PROD_EXTRACT(val) (((val) & REG_RING_PROD_MASK) >> \
+  REG_RING_PROD_SHIFT)
+
+#define TBT_REG_RING_CONS_EXTRACT(val) (((val) & REG_RING_CONS_MASK) >> \
+  REG_RING_CONS_SHIFT)
 /*
  * 32 bytes per entry, one entry for every hop (REG_HOP_COUNT)
  * 00: enum_ring_flags
@@ -77,6 +133,19 @@ struct ring_desc {
  * ..: unknown
  */
 #define REG_RX_OPTIONS_BASE0x29800
+#define REG_RX_OPTS_TX_E2E_HOP_ID_SHIFT12
+#define REG_RX_OPTS_TX_E2E_HOP_ID_MASK \
+   GENMASK(22, REG_RX_OPTS_TX_E2E_HOP_ID_SHIFT)
+#define REG_RX_OPTS_MASK_OFFSET4
+#define REG_RX_OPTS_MASK_EOF_SHIFT 0
+#define REG_RX_OPTS_MASK_EOF_MASK  GENMASK(15, REG_RX_OPTS_MASK_EOF_SHIFT)
+#define REG_RX_OPTS_MASK_SOF_SHIFT 16
+#define REG_RX_OPTS_MASK_SOF_MASK  GENMASK(31, REG_RX_OPTS_MASK_SOF_SHIFT)
+
+#define REG_OPTS_STEP  32
+#define REG_OPTS_E2E_ENBIT(28)
+#define REG_OPTS_RAW   BIT(30)
+#define REG_OPTS_VALID BIT(31)
 
 /*
  * three bitfields: tx, rx, rx overflow
@@ -86,6 +155,7 @@ struct ring_desc {
  */
 #define REG_RING_NOTIFY_BASE   0x37800
 #define RING_NOTIFY_REG_COUNT(nhi) ((31 + 3 * nhi->hop_count) / 32)
+#define REG_RING_NOTIFY_STEP   4
 
 /*
  * two bitfields: rx, tx
@@ -94,8 +164,47 @@ struct ring_desc {
  */
 #define REG_RING_INTERRUPT_BASE0x38200
 #define RING_INTERRUPT_REG_COUNT(nhi) ((31 + 2 * nhi->hop_count) / 32)
+#define REG_RING_INT_TX_PROCESSED(ring_num)BIT(ring_num)
+#define REG_RING_INT_RX_PROCESSED(ring_num, num_paths) BIT((ring_num) + \
+   (num_paths))
+#define RING_INT_DISABLE(base, val) iowrite32( \
+   ioread32((base) + REG_RING_INTERRUPT_BASE) & ~(val), \
+   (base) + REG_RING_IN

[PATCH v6 5/8] thunderbolt: Networking state machine

2016-08-01 Thread Amir Levy
Negotiation states that a peer goes through in order to establish
the communication with the second peer.
This includes communication with upper layer and additional
infrastructure support to communicate with the second peer through ICM.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 drivers/thunderbolt/icm/Makefile  |   2 +-
 drivers/thunderbolt/icm/icm_nhi.c | 303 ++-
 drivers/thunderbolt/icm/net.c | 793 ++
 drivers/thunderbolt/icm/net.h |  70 
 4 files changed, 1157 insertions(+), 11 deletions(-)
 create mode 100644 drivers/thunderbolt/icm/net.c

diff --git a/drivers/thunderbolt/icm/Makefile b/drivers/thunderbolt/icm/Makefile
index 3adfc35..624ee31 100644
--- a/drivers/thunderbolt/icm/Makefile
+++ b/drivers/thunderbolt/icm/Makefile
@@ -25,4 +25,4 @@
 

 
 obj-${CONFIG_THUNDERBOLT_ICM} += thunderbolt-icm.o
-thunderbolt-icm-objs := icm_nhi.o
+thunderbolt-icm-objs := icm_nhi.o net.o
diff --git a/drivers/thunderbolt/icm/icm_nhi.c 
b/drivers/thunderbolt/icm/icm_nhi.c
index bcb5c1b..b083f21c 100644
--- a/drivers/thunderbolt/icm/icm_nhi.c
+++ b/drivers/thunderbolt/icm/icm_nhi.c
@@ -74,6 +74,12 @@ static const struct nla_policy nhi_genl_policy[NHI_ATTR_MAX 
+ 1] = {
.len = TBT_ICM_RING_MAX_FRAME_SIZE },
[NHI_ATTR_MSG_FROM_ICM] = { .type = NLA_BINARY,
.len = TBT_ICM_RING_MAX_FRAME_SIZE },
+   [NHI_ATTR_LOCAL_ROUTE_STRING]   = {.len = sizeof(struct route_string)},
+   [NHI_ATTR_LOCAL_UUID]   = { .len = sizeof(uuid_be) },
+   [NHI_ATTR_REMOTE_UUID]  = { .len = sizeof(uuid_be) },
+   [NHI_ATTR_LOCAL_DEPTH]  = { .type = NLA_U8, },
+   [NHI_ATTR_ENABLE_FULL_E2E]  = { .type = NLA_FLAG, },
+   [NHI_ATTR_MATCH_FRAME_ID]   = { .type = NLA_FLAG, },
 };
 
 /* NHI genetlink family */
@@ -522,6 +528,29 @@ int nhi_mailbox(struct tbt_nhi_ctxt *nhi_ctxt, u32 cmd, 
u32 data, bool deinit)
return 0;
 }
 
+static inline bool nhi_is_path_disconnected(u32 cmd, u8 num_ports)
+{
+   return (cmd >= DISCONNECT_PORT_A_INTER_DOMAIN_PATH &&
+   cmd < (DISCONNECT_PORT_A_INTER_DOMAIN_PATH + num_ports));
+}
+
+static int nhi_mailbox_disconn_path(struct tbt_nhi_ctxt *nhi_ctxt, u32 cmd)
+   __releases(_list_mutex)
+{
+   struct port_net_dev *port;
+   u32 port_num = cmd - DISCONNECT_PORT_A_INTER_DOMAIN_PATH;
+
+   port = &(nhi_ctxt->net_devices[port_num]);
+   mutex_lock(>state_mutex);
+
+   mutex_unlock(_list_mutex);
+   port->medium_sts = MEDIUM_READY_FOR_APPROVAL;
+   if (port->net_dev)
+   negotiation_events(port->net_dev, MEDIUM_DISCONNECTED);
+   mutex_unlock(>state_mutex);
+   return  0;
+}
+
 static int nhi_mailbox_generic(struct tbt_nhi_ctxt *nhi_ctxt, u32 mb_cmd)
__releases(_list_mutex)
 {
@@ -571,13 +600,94 @@ static int nhi_genl_mailbox(__always_unused struct 
sk_buff *u_skb,
return -ERESTART;
 
nhi_ctxt = nhi_search_ctxt(*(u32 *)info->userhdr);
-   if (nhi_ctxt && !nhi_ctxt->d0_exit)
-   return nhi_mailbox_generic(nhi_ctxt, mb_cmd);
+   if (nhi_ctxt && !nhi_ctxt->d0_exit) {
+
+   /* rwsem is released later by the below functions */
+   if (nhi_is_path_disconnected(cmd, nhi_ctxt->num_ports))
+   return nhi_mailbox_disconn_path(nhi_ctxt, cmd);
+   else
+   return nhi_mailbox_generic(nhi_ctxt, mb_cmd);
+
+   }
 
mutex_unlock(_list_mutex);
return -ENODEV;
 }
 
+static int nhi_genl_approve_networking(__always_unused struct sk_buff *u_skb,
+  struct genl_info *info)
+{
+   struct tbt_nhi_ctxt *nhi_ctxt;
+   struct route_string *route_str;
+   int res = -ENODEV;
+   u8 port_num;
+
+   if (!info || !info->userhdr || !info->attrs ||
+   !info->attrs[NHI_ATTR_LOCAL_ROUTE_STRING] ||
+   !info->attrs[NHI_ATTR_LOCAL_UUID] ||
+   !info->attrs[NHI_ATTR_REMOTE_UUID] ||
+   !info->attrs[NHI_ATTR_LOCAL_DEPTH])
+   return -EINVAL;
+
+   /*
+* route_str is an unique topological address
+* used for approving remote controller
+*/
+   route_str = nla_data(info->attrs[NHI_ATTR_LOCAL_ROUTE_STRING]);
+   /* extracts the port we're connected to */
+   port_num = PORT_NUM_FROM_LINK(L0_PORT_NUM(route_str->lo));
+
+   if (mutex_lock_interruptible(_list_mutex))
+   return -ERESTART;
+
+   nhi_ctxt = nhi_search_ctxt(*(u32 *)info->userhdr);
+   if (nhi_ctxt && !nhi_ctxt->d0_exit) {
+   struct port_net_dev *port;
+
+   if (port_num

[PATCH v6 7/8] thunderbolt: Networking doc

2016-08-01 Thread Amir Levy
Adding Thunderbolt(TM) networking documentation.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 Documentation/00-INDEX   |   2 +
 Documentation/thunderbolt-networking.txt | 135 +++
 2 files changed, 137 insertions(+)
 create mode 100644 Documentation/thunderbolt-networking.txt

diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX
index cb9a6c6..80a6706 100644
--- a/Documentation/00-INDEX
+++ b/Documentation/00-INDEX
@@ -439,6 +439,8 @@ this_cpu_ops.txt
- List rationale behind and the way to use this_cpu operations.
 thermal/
- directory with information on managing thermal issues (CPU/temp)
+thunderbolt-networking.txt
+   - Thunderbolt(TM) Networking driver description.
 trace/
- directory with info on tracing technologies within linux
 unaligned-memory-access.txt
diff --git a/Documentation/thunderbolt-networking.txt 
b/Documentation/thunderbolt-networking.txt
new file mode 100644
index 000..e112313
--- /dev/null
+++ b/Documentation/thunderbolt-networking.txt
@@ -0,0 +1,135 @@
+Intel Thunderbolt(TM) Linux driver
+==
+
+Copyright(c) 2013 - 2016 Intel Corporation.
+
+Contact Information:
+Intel Thunderbolt mailing list <thunderbolt-softw...@lists.01.org>
+Edited by Michael Jamet <michael.ja...@intel.com>
+
+Overview
+
+
+Thunderbolt(TM) Networking mode is introduced with this driver.
+This kernel code creates an ethernet device utilized in computer to computer
+communication over a Thunderbolt cable.
+This driver has been added on the top of the existing thunderbolt driver
+for systems with firwmare (FW) based Thunderbolt controllers supporting
+Thunderbolt Networking.
+
+Files
+=
+
+- icm_nhi.c/h: These files allow communication with the FW (a.k.a ICM) based 
controller.
+   In addition, they create an interface for netlink communication 
with
+   a user space daemon.
+
+- net.c/net.h: These files implement the 'eth' interface for the 
Thunderbolt(TM)
+   networking.
+
+Interface to user space
+===
+
+The interface to the user space module is implemented through a Generic 
Netlink.
+In order to be accessed by the user space module, both kernel and user space
+modules have to register with the same GENL_NAME. In our case, this is
+simply "thunderbolt".
+The registration is done at driver initialization time for all instances of
+the Thunderbolt controllers.
+The communication is then carried through pre-defined Thunderbolt messages.
+Each specific message has a callback function that is called when
+the related message is received.
+
+The messages are defined as follows:
+* NHI_CMD_UNSPEC: Not used.
+* NHI_CMD_SUBSCRIBE: Subscription request from daemon to driver to open the
+  communication channel.
+* NHI_CMD_UNSUBSCRIBE: Request from daemon to driver to unsubscribe
+  to close communication channel.
+* NHI_CMD_QUERY_INFORMATION: Request information from the driver such as
+  driver version, FW version offset, number of ports in the controller
+  and DMA port.
+* NHI_CMD_MSG_TO_ICM: Message from user space module to FW.
+* NHI_CMD_MSG_FROM_ICM: Response from FW to user space module.
+* NHI_CMD_MAILBOX: Message that uses mailbox mechanism such as FW policy
+  changes or disconnect path.
+* NHI_CMD_APPROVE_TBT_NETWORKING: Request from user space
+  module to FW to establish path.
+* NHI_CMD_ICM_IN_SAFE_MODE: Indication that the FW has entered safe mode.
+
+Communication with ICM (Firmware)
+=
+
+The communication with ICM is principally achieved through
+a DMA mechanism on Ring 0.
+The driver allocates a shared memory that is physically mapped onto
+the DMA physical space at Ring 0.
+
+Interrupts
+==
+
+Thunderbolt relies on MSI-X interrupts.
+The MSI-X vector is allocated as follows:
+ICM
+ - Tx: MSI-X vector index 0
+ - Rx: MSI-X vector index 1
+
+Port 0
+ - Tx: MSI-X vector index 2
+ - Rx: MSI-X vector index 3
+
+Port 1
+ - Tx: MSI-X vector index 4
+ - Rx: MSI-X vector index 5
+
+ICM interrupts are used for communication with ICM only.
+Port 0 and Port 1 interrupts are used for Thunderbolt Networking
+communications.
+In case MSI-X is not available, the driver requests to enable MSI only.
+
+Mutexes, semaphores and spinlocks
+=
+
+The driver should be able to operate in an environment where hardware
+is asynchronously accessed by multiple entities such as netlink,
+multiple controllers etc.
+
+* send_sem: This semaphore enforces unique sender (one sender at a time)
+  to avoid wrong impairing with responses. FW may process one message
+  at the time.
+* d0_exit_send_mutex: This mutex protects D0 exit (D3) situation
+  to avoid continuing to send messages to FW.
+* d0_exit_mailbox_mutex: This mutex protects D0 exit (D3) situation to
+  avoid continuing to send commands to mailbox.
+* mailbo

[PATCH v6 0/8] thunderbolt: Introducing Thunderbolt(TM) networking

2016-08-01 Thread Amir Levy
This is version 6 of Thunderbolt(TM) driver for non-Apple hardware.

Changes since v5:
 - Removed the padding of short packets in receive
 - Replaced RW semaphore with mutex
 - Cleanup

These patches were pushed to GitHub where they can be reviewed more
comfortably with green/red highlighting:
https://github.com/01org/thunderbolt-software-kernel-tree

Daemon code:
https://github.com/01org/thunderbolt-software-daemon

For reference, here's a link to version 5:
[v5]:   https://lkml.org/lkml/2016/7/28/85

Amir Levy (8):
  thunderbolt: Macro rename
  thunderbolt: Updating the register definitions
  thunderbolt: Kconfig for Thunderbolt(TM) networking
  thunderbolt: Communication with the ICM (firmware)
  thunderbolt: Networking state machine
  thunderbolt: Networking transmit and receive
  thunderbolt: Networking doc
  thunderbolt: Adding maintainer entry

 Documentation/00-INDEX   |2 +
 Documentation/thunderbolt-networking.txt |  135 ++
 MAINTAINERS  |8 +-
 drivers/thunderbolt/Kconfig  |   25 +-
 drivers/thunderbolt/Makefile |3 +-
 drivers/thunderbolt/icm/Makefile |   28 +
 drivers/thunderbolt/icm/icm_nhi.c| 1622 +
 drivers/thunderbolt/icm/icm_nhi.h|   93 ++
 drivers/thunderbolt/icm/net.c| 2264 ++
 drivers/thunderbolt/icm/net.h|  297 
 drivers/thunderbolt/nhi_regs.h   |  115 +-
 11 files changed, 4583 insertions(+), 9 deletions(-)
 create mode 100644 Documentation/thunderbolt-networking.txt
 create mode 100644 drivers/thunderbolt/icm/Makefile
 create mode 100644 drivers/thunderbolt/icm/icm_nhi.c
 create mode 100644 drivers/thunderbolt/icm/icm_nhi.h
 create mode 100644 drivers/thunderbolt/icm/net.c
 create mode 100644 drivers/thunderbolt/icm/net.h

-- 
2.7.4



[PATCH v6 4/8] thunderbolt: Communication with the ICM (firmware)

2016-08-01 Thread Amir Levy
Firmware-based (a.k.a ICM - Intel Connection Manager) controller is
used for establishing and maintaining the Thunderbolt Networking
connection. We need to be able to communicate with it.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 drivers/thunderbolt/Makefile  |1 +
 drivers/thunderbolt/icm/Makefile  |   28 +
 drivers/thunderbolt/icm/icm_nhi.c | 1324 +
 drivers/thunderbolt/icm/icm_nhi.h |   93 +++
 drivers/thunderbolt/icm/net.h |  227 +++
 5 files changed, 1673 insertions(+)
 create mode 100644 drivers/thunderbolt/icm/Makefile
 create mode 100644 drivers/thunderbolt/icm/icm_nhi.c
 create mode 100644 drivers/thunderbolt/icm/icm_nhi.h
 create mode 100644 drivers/thunderbolt/icm/net.h

diff --git a/drivers/thunderbolt/Makefile b/drivers/thunderbolt/Makefile
index 7a85bd1..b6aa6a3 100644
--- a/drivers/thunderbolt/Makefile
+++ b/drivers/thunderbolt/Makefile
@@ -1,3 +1,4 @@
 obj-${CONFIG_THUNDERBOLT_APPLE} := thunderbolt.o
 thunderbolt-objs := nhi.o ctl.o tb.o switch.o cap.o path.o tunnel_pci.o 
eeprom.o
 
+obj-${CONFIG_THUNDERBOLT_ICM} += icm/
diff --git a/drivers/thunderbolt/icm/Makefile b/drivers/thunderbolt/icm/Makefile
new file mode 100644
index 000..3adfc35
--- /dev/null
+++ b/drivers/thunderbolt/icm/Makefile
@@ -0,0 +1,28 @@
+
+#
+# Intel Thunderbolt(TM) driver
+# Copyright(c) 2014 - 2016 Intel Corporation.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms and conditions of the GNU General Public License,
+# version 2, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+# more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# The full GNU General Public License is included in this distribution in
+# the file called "COPYING".
+#
+# Contact Information:
+# Intel Thunderbolt Mailing List <thunderbolt-softw...@lists.01.org>
+# Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+#
+
+
+obj-${CONFIG_THUNDERBOLT_ICM} += thunderbolt-icm.o
+thunderbolt-icm-objs := icm_nhi.o
diff --git a/drivers/thunderbolt/icm/icm_nhi.c 
b/drivers/thunderbolt/icm/icm_nhi.c
new file mode 100644
index 000..bcb5c1b
--- /dev/null
+++ b/drivers/thunderbolt/icm/icm_nhi.c
@@ -0,0 +1,1324 @@
+/***
+ *
+ * Intel Thunderbolt(TM) driver
+ * Copyright(c) 2014 - 2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Intel Thunderbolt Mailing List <thunderbolt-softw...@lists.01.org>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ 
**/
+
+#include 
+#include 
+#include 
+#include 
+#include "icm_nhi.h"
+#include "net.h"
+
+#define NHI_GENL_VERSION 1
+#define NHI_GENL_NAME DRV_NAME
+
+#define DEVICE_DATA(num_ports, dma_port, nvm_ver_offset, nvm_auth_on_boot,\
+   support_full_e2e) \
+   ((num_ports) | ((dma_port) << 4) | ((nvm_ver_offset) << 10) | \
+((nvm_auth_on_boot) << 22) | ((support_full_e2e) << 23))
+#define DEVICE_DATA_NUM_PORTS(device_data) ((device_data) & 0xf)
+#define DEVICE_DATA_DMA_PORT(device_data) (((device_data) >> 4) & 0x3f)
+#define DEVICE_DATA_NVM_VER_OFFSET(device_data) (((device_data) >> 10) & 0xfff)
+#define DEVICE_DATA_NVM_AUTH_ON_BOOT(device_data) (((device_data) >> 22) & 0x1)
+#define DEVICE_DATA_SUPPORT_FULL_E2E(device_data) (((device_data) >> 23) & 0x1)
+
+#define USEC_TO_256_NSECS(usec) DIV_ROUND_UP((usec) * NSEC_PER_USEC, 256)
+
+/* NHI genetlink commands */
+enum {
+   NHI_CMD_UNSPEC,
+   NHI_CMD_SUBSCRIBE,
+  

[PATCH v5 3/8] thunderbolt: Kconfig for Thunderbolt(TM) networking

2016-07-28 Thread Amir Levy
Updating the Kconfig Thunderbolt(TM) description.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 drivers/thunderbolt/Kconfig  | 25 +
 drivers/thunderbolt/Makefile |  2 +-
 2 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/drivers/thunderbolt/Kconfig b/drivers/thunderbolt/Kconfig
index c121acc..d34b0f5 100644
--- a/drivers/thunderbolt/Kconfig
+++ b/drivers/thunderbolt/Kconfig
@@ -1,13 +1,30 @@
-menuconfig THUNDERBOLT
-   tristate "Thunderbolt support for Apple devices"
+config THUNDERBOLT
+   tristate "Thunderbolt(TM) support"
depends on PCI
select CRC32
help
- Cactus Ridge Thunderbolt Controller driver
+ Thunderbolt(TM) Controller driver
+
+if THUNDERBOLT
+
+config THUNDERBOLT_APPLE
+   tristate "Apple hardware support"
+   help
  This driver is required if you want to hotplug Thunderbolt devices on
  Apple hardware.
 
  Device chaining is currently not supported.
 
- To compile this driver a module, choose M here. The module will be
+ To compile this driver as a module, choose M here. The module will be
  called thunderbolt.
+
+config THUNDERBOLT_ICM
+   tristate "Thunderbolt(TM) Networking"
+   help
+ This driver is required if you want Thunderbolt(TM) Networking on
+ non-Apple hardware.
+
+ To compile this driver as a module, choose M here. The module will be
+ called thunderbolt_icm.
+
+endif
diff --git a/drivers/thunderbolt/Makefile b/drivers/thunderbolt/Makefile
index 5d1053c..7a85bd1 100644
--- a/drivers/thunderbolt/Makefile
+++ b/drivers/thunderbolt/Makefile
@@ -1,3 +1,3 @@
-obj-${CONFIG_THUNDERBOLT} := thunderbolt.o
+obj-${CONFIG_THUNDERBOLT_APPLE} := thunderbolt.o
 thunderbolt-objs := nhi.o ctl.o tb.o switch.o cap.o path.o tunnel_pci.o 
eeprom.o
 
-- 
2.7.4



[PATCH v5 5/8] thunderbolt: Networking state machine

2016-07-28 Thread Amir Levy
Negotiation states that a peer goes through in order to establish
the communication with the second peer.
This includes communication with upper layer and additional
infrastructure support to communicate with the second peer through ICM.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 drivers/thunderbolt/icm/Makefile  |   2 +-
 drivers/thunderbolt/icm/icm_nhi.c | 303 ++-
 drivers/thunderbolt/icm/net.c | 792 ++
 drivers/thunderbolt/icm/net.h |  70 
 4 files changed, 1156 insertions(+), 11 deletions(-)
 create mode 100644 drivers/thunderbolt/icm/net.c

diff --git a/drivers/thunderbolt/icm/Makefile b/drivers/thunderbolt/icm/Makefile
index 3adfc35..624ee31 100644
--- a/drivers/thunderbolt/icm/Makefile
+++ b/drivers/thunderbolt/icm/Makefile
@@ -25,4 +25,4 @@
 

 
 obj-${CONFIG_THUNDERBOLT_ICM} += thunderbolt-icm.o
-thunderbolt-icm-objs := icm_nhi.o
+thunderbolt-icm-objs := icm_nhi.o net.o
diff --git a/drivers/thunderbolt/icm/icm_nhi.c 
b/drivers/thunderbolt/icm/icm_nhi.c
index 2106dea..e491b0e 100644
--- a/drivers/thunderbolt/icm/icm_nhi.c
+++ b/drivers/thunderbolt/icm/icm_nhi.c
@@ -101,6 +101,12 @@ static const struct nla_policy 
nhi_genl_policy[NHI_ATTR_MAX + 1] = {
.len = TBT_ICM_RING_MAX_FRAME_SIZE },
[NHI_ATTR_MSG_FROM_ICM] = { .type = NLA_BINARY,
.len = TBT_ICM_RING_MAX_FRAME_SIZE },
+   [NHI_ATTR_LOCAL_ROUTE_STRING]   = {.len = sizeof(struct route_string)},
+   [NHI_ATTR_LOCAL_UUID]   = { .len = sizeof(uuid_be) },
+   [NHI_ATTR_REMOTE_UUID]  = { .len = sizeof(uuid_be) },
+   [NHI_ATTR_LOCAL_DEPTH]  = { .type = NLA_U8, },
+   [NHI_ATTR_ENABLE_FULL_E2E]  = { .type = NLA_FLAG, },
+   [NHI_ATTR_MATCH_FRAME_ID]   = { .type = NLA_FLAG, },
 };
 
 /* NHI genetlink family */
@@ -542,6 +548,29 @@ int nhi_mailbox(struct tbt_nhi_ctxt *nhi_ctxt, u32 cmd, 
u32 data, bool deinit)
return 0;
 }
 
+static inline bool nhi_is_path_disconnected(u32 cmd, u8 num_ports)
+{
+   return (cmd >= DISCONNECT_PORT_A_INTER_DOMAIN_PATH &&
+   cmd < (DISCONNECT_PORT_A_INTER_DOMAIN_PATH + num_ports));
+}
+
+static int nhi_mailbox_disconn_path(struct tbt_nhi_ctxt *nhi_ctxt, u32 cmd)
+   __releases(_list_rwsem)
+{
+   struct port_net_dev *port;
+   u32 port_num = cmd - DISCONNECT_PORT_A_INTER_DOMAIN_PATH;
+
+   port = &(nhi_ctxt->net_devices[port_num]);
+   mutex_lock(>state_mutex);
+
+   up_read(_list_rwsem);
+   port->medium_sts = MEDIUM_READY_FOR_APPROVAL;
+   if (port->net_dev)
+   negotiation_events(port->net_dev, MEDIUM_DISCONNECTED);
+   mutex_unlock(>state_mutex);
+   return  0;
+}
+
 static int nhi_mailbox_generic(struct tbt_nhi_ctxt *nhi_ctxt, u32 mb_cmd)
__releases(_list_rwsem)
 {
@@ -590,13 +619,93 @@ static int nhi_genl_mailbox(__always_unused struct 
sk_buff *u_skb,
down_read(_list_rwsem);
 
nhi_ctxt = nhi_search_ctxt(*(u32 *)info->userhdr);
-   if (nhi_ctxt && !nhi_ctxt->d0_exit)
-   return nhi_mailbox_generic(nhi_ctxt, mb_cmd);
+   if (nhi_ctxt && !nhi_ctxt->d0_exit) {
+
+   /* rwsem is released later by the below functions */
+   if (nhi_is_path_disconnected(cmd, nhi_ctxt->num_ports))
+   return nhi_mailbox_disconn_path(nhi_ctxt, cmd);
+   else
+   return nhi_mailbox_generic(nhi_ctxt, mb_cmd);
+
+   }
 
up_read(_list_rwsem);
return -ENODEV;
 }
 
+static int nhi_genl_approve_networking(__always_unused struct sk_buff *u_skb,
+  struct genl_info *info)
+{
+   struct tbt_nhi_ctxt *nhi_ctxt;
+   struct route_string *route_str;
+   int res = -ENODEV;
+   u8 port_num;
+
+   if (!info || !info->userhdr || !info->attrs ||
+   !info->attrs[NHI_ATTR_LOCAL_ROUTE_STRING] ||
+   !info->attrs[NHI_ATTR_LOCAL_UUID] ||
+   !info->attrs[NHI_ATTR_REMOTE_UUID] ||
+   !info->attrs[NHI_ATTR_LOCAL_DEPTH])
+   return -EINVAL;
+
+   /*
+* route_str is an unique topological address
+* used for approving remote controller
+*/
+   route_str = nla_data(info->attrs[NHI_ATTR_LOCAL_ROUTE_STRING]);
+   /* extracts the port we're connected to */
+   port_num = PORT_NUM_FROM_LINK(L0_PORT_NUM(route_str->lo));
+
+   down_read(_list_rwsem);
+
+   nhi_ctxt = nhi_search_ctxt(*(u32 *)info->userhdr);
+   if (nhi_ctxt && !nhi_ctxt->d0_exit) {
+   struct port_net_dev *port;
+
+   if (port_num >= nhi_ctxt->num_ports) {
+   res = -EINVAL;
+

[PATCH v5 8/8] thunderbolt: Adding maintainer entry

2016-07-28 Thread Amir Levy
Add Amir Levy as maintainer for Thunderbolt(TM) ICM driver

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 MAINTAINERS | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 771c31c..5f24eb2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10141,7 +10141,13 @@ F: include/uapi/linux/stm.h
 THUNDERBOLT DRIVER
 M: Andreas Noever <andreas.noe...@gmail.com>
 S: Maintained
-F: drivers/thunderbolt/
+F: drivers/thunderbolt/*
+
+THUNDERBOLT ICM DRIVER
+M:     Amir Levy <amir.jer.l...@intel.com>
+S: Maintained
+F: drivers/thunderbolt/icm/
+F: Documentation/thunderbolt-networking.txt
 
 TI BQ27XXX POWER SUPPLY DRIVER
 R: Andrew F. Davis <a...@ti.com>
-- 
2.7.4



[PATCH v5 4/8] thunderbolt: Communication with the ICM (firmware)

2016-07-28 Thread Amir Levy
Firmware-based (a.k.a ICM - Intel Connection Manager) controller is
used for establishing and maintaining the Thunderbolt Networking
connection. We need to be able to communicate with it.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 drivers/thunderbolt/Makefile  |1 +
 drivers/thunderbolt/icm/Makefile  |   28 +
 drivers/thunderbolt/icm/icm_nhi.c | 1343 +
 drivers/thunderbolt/icm/icm_nhi.h |   93 +++
 drivers/thunderbolt/icm/net.h |  200 ++
 5 files changed, 1665 insertions(+)
 create mode 100644 drivers/thunderbolt/icm/Makefile
 create mode 100644 drivers/thunderbolt/icm/icm_nhi.c
 create mode 100644 drivers/thunderbolt/icm/icm_nhi.h
 create mode 100644 drivers/thunderbolt/icm/net.h

diff --git a/drivers/thunderbolt/Makefile b/drivers/thunderbolt/Makefile
index 7a85bd1..b6aa6a3 100644
--- a/drivers/thunderbolt/Makefile
+++ b/drivers/thunderbolt/Makefile
@@ -1,3 +1,4 @@
 obj-${CONFIG_THUNDERBOLT_APPLE} := thunderbolt.o
 thunderbolt-objs := nhi.o ctl.o tb.o switch.o cap.o path.o tunnel_pci.o 
eeprom.o
 
+obj-${CONFIG_THUNDERBOLT_ICM} += icm/
diff --git a/drivers/thunderbolt/icm/Makefile b/drivers/thunderbolt/icm/Makefile
new file mode 100644
index 000..3adfc35
--- /dev/null
+++ b/drivers/thunderbolt/icm/Makefile
@@ -0,0 +1,28 @@
+
+#
+# Intel Thunderbolt(TM) driver
+# Copyright(c) 2014 - 2016 Intel Corporation.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms and conditions of the GNU General Public License,
+# version 2, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+# more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# The full GNU General Public License is included in this distribution in
+# the file called "COPYING".
+#
+# Contact Information:
+# Intel Thunderbolt Mailing List <thunderbolt-softw...@lists.01.org>
+# Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+#
+
+
+obj-${CONFIG_THUNDERBOLT_ICM} += thunderbolt-icm.o
+thunderbolt-icm-objs := icm_nhi.o
diff --git a/drivers/thunderbolt/icm/icm_nhi.c 
b/drivers/thunderbolt/icm/icm_nhi.c
new file mode 100644
index 000..2106dea
--- /dev/null
+++ b/drivers/thunderbolt/icm/icm_nhi.c
@@ -0,0 +1,1343 @@
+/***
+ *
+ * Intel Thunderbolt(TM) driver
+ * Copyright(c) 2014 - 2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Intel Thunderbolt Mailing List <thunderbolt-softw...@lists.01.org>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ 
**/
+
+#include 
+#include 
+#include 
+#include 
+#include "icm_nhi.h"
+#include "net.h"
+
+#define NHI_GENL_VERSION 1
+#define NHI_GENL_NAME DRV_NAME
+
+#define DEVICE_DATA(num_ports, dma_port, nvm_ver_offset, nvm_auth_on_boot,\
+   support_full_e2e) \
+   ((num_ports) | ((dma_port) << 4) | ((nvm_ver_offset) << 10) | \
+((nvm_auth_on_boot) << 22) | ((support_full_e2e) << 23))
+#define DEVICE_DATA_NUM_PORTS(device_data) ((device_data) & 0xf)
+#define DEVICE_DATA_DMA_PORT(device_data) (((device_data) >> 4) & 0x3f)
+#define DEVICE_DATA_NVM_VER_OFFSET(device_data) (((device_data) >> 10) & 0xfff)
+#define DEVICE_DATA_NVM_AUTH_ON_BOOT(device_data) (((device_data) >> 22) & 0x1)
+#define DEVICE_DATA_SUPPORT_FULL_E2E(device_data) (((device_data) >> 23) & 0x1)
+
+#define USEC_TO_256_NSECS(usec) DIV_ROUND_UP((usec) * NSEC_PER_USEC, 256)
+
+/*
+ * FW->SW responses
+ * RC = response code
+ */
+enum {
+   RC_GET_TBT_

[PATCH v5 7/8] thunderbolt: Networking doc

2016-07-28 Thread Amir Levy
Adding Thunderbolt(TM) networking documentation.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 Documentation/00-INDEX   |   2 +
 Documentation/thunderbolt-networking.txt | 135 +++
 2 files changed, 137 insertions(+)
 create mode 100644 Documentation/thunderbolt-networking.txt

diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX
index cb9a6c6..80a6706 100644
--- a/Documentation/00-INDEX
+++ b/Documentation/00-INDEX
@@ -439,6 +439,8 @@ this_cpu_ops.txt
- List rationale behind and the way to use this_cpu operations.
 thermal/
- directory with information on managing thermal issues (CPU/temp)
+thunderbolt-networking.txt
+   - Thunderbolt(TM) Networking driver description.
 trace/
- directory with info on tracing technologies within linux
 unaligned-memory-access.txt
diff --git a/Documentation/thunderbolt-networking.txt 
b/Documentation/thunderbolt-networking.txt
new file mode 100644
index 000..b7714cf
--- /dev/null
+++ b/Documentation/thunderbolt-networking.txt
@@ -0,0 +1,135 @@
+Intel Thunderbolt(TM) Linux driver
+==
+
+Copyright(c) 2013 - 2016 Intel Corporation.
+
+Contact Information:
+Intel Thunderbolt mailing list <thunderbolt-softw...@lists.01.org>
+Edited by Michael Jamet <michael.ja...@intel.com>
+
+Overview
+
+
+Thunderbolt(TM) Networking mode is introduced with this driver.
+This kernel code creates an ethernet device utilized in computer to computer
+communication over a Thunderbolt cable.
+This driver has been added on the top of the existing thunderbolt driver
+for systems with firwmare (FW) based Thunderbolt controllers supporting
+Thunderbolt Networking.
+
+Files
+=
+
+- icm_nhi.c/h: These files allow communication with the FW (a.k.a ICM) based 
controller.
+   In addition, they create an interface for netlink communication 
with
+   a user space daemon.
+
+- net.c/net.h: These files implement the 'eth' interface for the 
Thunderbolt(TM)
+   networking.
+
+Interface to user space
+===
+
+The interface to the user space module is implemented through a Generic 
Netlink.
+In order to be accessed by the user space module, both kernel and user space
+modules have to register with the same GENL_NAME. In our case, this is
+simply "thunderbolt".
+The registration is done at driver initialization time for all instances of
+the Thunderbolt controllers.
+The communication is then carried through pre-defined Thunderbolt messages.
+Each specific message has a callback function that is called when
+the related message is received.
+
+The messages are defined as follows:
+* NHI_CMD_UNSPEC: Not used.
+* NHI_CMD_SUBSCRIBE: Subscription request from daemon to driver to open the
+  communication channel.
+* NHI_CMD_UNSUBSCRIBE: Request from daemon to driver to unsubscribe
+  to close communication channel.
+* NHI_CMD_QUERY_INFORMATION: Request information from the driver such as
+  driver version, FW version offset, number of ports in the controller
+  and DMA port.
+* NHI_CMD_MSG_TO_ICM: Message from user space module to FW.
+* NHI_CMD_MSG_FROM_ICM: Response from FW to user space module.
+* NHI_CMD_MAILBOX: Message that uses mailbox mechanism such as FW policy
+  changes or disconnect path.
+* NHI_CMD_APPROVE_TBT_NETWORKING: Request from user space
+  module to FW to establish path.
+* NHI_CMD_ICM_IN_SAFE_MODE: Indication that the FW has entered safe mode.
+
+Communication with ICM (Firmware)
+=
+
+The communication with ICM is principally achieved through
+a DMA mechanism on Ring 0.
+The driver allocates a shared memory that is physically mapped onto
+the DMA physical space at Ring 0.
+
+Interrupts
+==
+
+Thunderbolt relies on MSI-X interrupts.
+The MSI-X vector is allocated as follows:
+ICM
+ - Tx: MSI-X vector index 0
+ - Rx: MSI-X vector index 1
+
+Port 0
+ - Tx: MSI-X vector index 2
+ - Rx: MSI-X vector index 3
+
+Port 1
+ - Tx: MSI-X vector index 4
+ - Rx: MSI-X vector index 5
+
+ICM interrupts are used for communication with ICM only.
+Port 0 and Port 1 interrupts are used for Thunderbolt Networking
+communications.
+In case MSI-X is not available, the driver requests to enable MSI only.
+
+Mutexes, semaphores and spinlocks
+=
+
+The driver should be able to operate in an environment where hardware
+is asynchronously accessed by multiple entities such as netlink,
+multiple controllers etc.
+
+* send_sem: This semaphore enforces unique sender (one sender at a time)
+  to avoid wrong impairing with responses. FW may process one message
+  at the time.
+* d0_exit_send_mutex: This mutex protects D0 exit (D3) situation
+  to avoid continuing to send messages to FW.
+* d0_exit_mailbox_mutex: This mutex protects D0 exit (D3) situation to
+  avoid continuing to send commands to mailbox.
+* mailbo

[PATCH v5 2/8] thunderbolt: Updating the register definitions

2016-07-28 Thread Amir Levy
Adding more Thunderbolt(TM) register definitions
and some helper macros.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 drivers/thunderbolt/nhi_regs.h | 109 +
 1 file changed, 109 insertions(+)

diff --git a/drivers/thunderbolt/nhi_regs.h b/drivers/thunderbolt/nhi_regs.h
index 75cf069..b8e961f 100644
--- a/drivers/thunderbolt/nhi_regs.h
+++ b/drivers/thunderbolt/nhi_regs.h
@@ -9,6 +9,11 @@
 
 #include 
 
+#define NHI_MMIO_BAR 0
+
+#define TBT_RING_MIN_NUM_BUFFERS   2
+#define TBT_RING_MAX_FRAME_SIZE(4 * 1024)
+
 enum ring_flags {
RING_FLAG_ISOCH_ENABLE = 1 << 27, /* TX only? */
RING_FLAG_E2E_FLOW_CONTROL = 1 << 28,
@@ -39,6 +44,33 @@ struct ring_desc {
u32 time; /* write zero */
 } __packed;
 
+/**
+ * struct tbt_buf_desc - TX/RX ring buffer descriptor.
+ * This is same as struct ring_desc, but without the use of bitfields and
+ * with explicit endianity.
+ */
+struct tbt_buf_desc {
+   __le64 phys;
+   __le32 attributes;
+   __le32 time;
+};
+
+#define DESC_ATTR_LEN_SHIFT0
+#define DESC_ATTR_LEN_MASK GENMASK(11, DESC_ATTR_LEN_SHIFT)
+#define DESC_ATTR_EOF_SHIFT12
+#define DESC_ATTR_EOF_MASK GENMASK(15, DESC_ATTR_EOF_SHIFT)
+#define DESC_ATTR_SOF_SHIFT16
+#define DESC_ATTR_SOF_MASK GENMASK(19, DESC_ATTR_SOF_SHIFT)
+#define DESC_ATTR_TX_ISOCH_DMA_EN  BIT(20) /* TX */
+#define DESC_ATTR_RX_CRC_ERR   BIT(20) /* RX after use */
+#define DESC_ATTR_DESC_DONEBIT(21)
+#define DESC_ATTR_REQ_STS  BIT(22) /* TX and RX before use */
+#define DESC_ATTR_RX_BUF_OVRN_ERR  BIT(22) /* RX after use */
+#define DESC_ATTR_INT_EN   BIT(23)
+#define DESC_ATTR_OFFSET_SHIFT 24
+#define DESC_ATTR_OFFSET_MASK  GENMASK(31, DESC_ATTR_OFFSET_SHIFT)
+
+
 /* NHI registers in bar 0 */
 
 /*
@@ -60,6 +92,30 @@ struct ring_desc {
  */
 #define REG_RX_RING_BASE   0x08000
 
+#define REG_RING_STEP  16
+#define REG_RING_PHYS_LO_OFFSET0
+#define REG_RING_PHYS_HI_OFFSET4
+#define REG_RING_CONS_PROD_OFFSET  8   /* cons - RO, prod - RW */
+#define REG_RING_CONS_SHIFT0
+#define REG_RING_CONS_MASK GENMASK(15, REG_RING_CONS_SHIFT)
+#define REG_RING_PROD_SHIFT16
+#define REG_RING_PROD_MASK GENMASK(31, REG_RING_PROD_SHIFT)
+#define REG_RING_SIZE_OFFSET   12
+#define REG_RING_SIZE_SHIFT0
+#define REG_RING_SIZE_MASK GENMASK(15, REG_RING_SIZE_SHIFT)
+#define REG_RING_BUF_SIZE_SHIFT16
+#define REG_RING_BUF_SIZE_MASK GENMASK(27, REG_RING_BUF_SIZE_SHIFT)
+
+#define TBT_RING_CONS_PROD_REG(iobase, ringbase, ringnumber) \
+ ((iobase) + (ringbase) + \
+ ((ringnumber) * REG_RING_STEP) + \
+ REG_RING_CONS_PROD_OFFSET)
+
+#define TBT_REG_RING_PROD_EXTRACT(val) (((val) & REG_RING_PROD_MASK) >> \
+  REG_RING_PROD_SHIFT)
+
+#define TBT_REG_RING_CONS_EXTRACT(val) (((val) & REG_RING_CONS_MASK) >> \
+  REG_RING_CONS_SHIFT)
 /*
  * 32 bytes per entry, one entry for every hop (REG_HOP_COUNT)
  * 00: enum_ring_flags
@@ -77,6 +133,19 @@ struct ring_desc {
  * ..: unknown
  */
 #define REG_RX_OPTIONS_BASE0x29800
+#define REG_RX_OPTS_TX_E2E_HOP_ID_SHIFT12
+#define REG_RX_OPTS_TX_E2E_HOP_ID_MASK \
+   GENMASK(22, REG_RX_OPTS_TX_E2E_HOP_ID_SHIFT)
+#define REG_RX_OPTS_MASK_OFFSET4
+#define REG_RX_OPTS_MASK_EOF_SHIFT 0
+#define REG_RX_OPTS_MASK_EOF_MASK  GENMASK(15, REG_RX_OPTS_MASK_EOF_SHIFT)
+#define REG_RX_OPTS_MASK_SOF_SHIFT 16
+#define REG_RX_OPTS_MASK_SOF_MASK  GENMASK(31, REG_RX_OPTS_MASK_SOF_SHIFT)
+
+#define REG_OPTS_STEP  32
+#define REG_OPTS_E2E_ENBIT(28)
+#define REG_OPTS_RAW   BIT(30)
+#define REG_OPTS_VALID BIT(31)
 
 /*
  * three bitfields: tx, rx, rx overflow
@@ -86,6 +155,7 @@ struct ring_desc {
  */
 #define REG_RING_NOTIFY_BASE   0x37800
 #define RING_NOTIFY_REG_COUNT(nhi) ((31 + 3 * nhi->hop_count) / 32)
+#define REG_RING_NOTIFY_STEP   4
 
 /*
  * two bitfields: rx, tx
@@ -94,8 +164,47 @@ struct ring_desc {
  */
 #define REG_RING_INTERRUPT_BASE0x38200
 #define RING_INTERRUPT_REG_COUNT(nhi) ((31 + 2 * nhi->hop_count) / 32)
+#define REG_RING_INT_TX_PROCESSED(ring_num)BIT(ring_num)
+#define REG_RING_INT_RX_PROCESSED(ring_num, num_paths) BIT((ring_num) + \
+   (num_paths))
+#define RING_INT_DISABLE(base, val) iowrite32( \
+   ioread32((base) + REG_RING_INTERRUPT_BASE) & ~(val), \
+   (base) + REG_RING_IN

[PATCH v5 6/8] thunderbolt: Networking transmit and receive

2016-07-28 Thread Amir Levy
Handling the transmission to second peer and receiving from it.
This includes communication with upper layer, the network stack
and configuration of Thunderbolt(TM) HW.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 drivers/thunderbolt/icm/icm_nhi.c |   15 +
 drivers/thunderbolt/icm/net.c | 1475 +
 2 files changed, 1490 insertions(+)

diff --git a/drivers/thunderbolt/icm/icm_nhi.c 
b/drivers/thunderbolt/icm/icm_nhi.c
index e491b0e..efadf9c 100644
--- a/drivers/thunderbolt/icm/icm_nhi.c
+++ b/drivers/thunderbolt/icm/icm_nhi.c
@@ -1055,6 +1055,7 @@ static irqreturn_t nhi_msi(int __always_unused irq, void 
*data)
 {
struct tbt_nhi_ctxt *nhi_ctxt = data;
u32 isr0, isr1, imr0, imr1;
+   int i;
 
/* clear on read */
isr0 = ioread32(nhi_ctxt->iobase + REG_RING_NOTIFY_BASE);
@@ -1077,6 +1078,20 @@ static irqreturn_t nhi_msi(int __always_unused irq, void 
*data)
 
spin_unlock(_ctxt->lock);
 
+   for (i = 0; i < nhi_ctxt->num_ports; ++i) {
+   struct net_device *net_dev =
+   nhi_ctxt->net_devices[i].net_dev;
+   if (net_dev) {
+   u8 path = PATH_FROM_PORT(nhi_ctxt->num_paths, i);
+
+   if (isr0 & REG_RING_INT_RX_PROCESSED(
+   path, nhi_ctxt->num_paths))
+   tbt_net_rx_msi(net_dev);
+   if (isr0 & REG_RING_INT_TX_PROCESSED(path))
+   tbt_net_tx_msi(net_dev);
+   }
+   }
+
if (isr0 & REG_RING_INT_RX_PROCESSED(TBT_ICM_RING_NUM,
 nhi_ctxt->num_paths))
schedule_work(_ctxt->icm_msgs_work);
diff --git a/drivers/thunderbolt/icm/net.c b/drivers/thunderbolt/icm/net.c
index 75801b5..6ce7c18 100644
--- a/drivers/thunderbolt/icm/net.c
+++ b/drivers/thunderbolt/icm/net.c
@@ -134,6 +134,17 @@ struct approve_inter_domain_connection_cmd {
 
 };
 
+struct tbt_frame_header {
+   /* size of the data with the frame */
+   __le32 frame_size;
+   /* running index on the frames */
+   __le16 frame_index;
+   /* ID of the frame to match frames to specific packet */
+   __le16 frame_id;
+   /* how many frames assembles a full packet */
+   __le32 frame_count;
+};
+
 enum neg_event {
RECEIVE_LOGOUT = NUM_MEDIUM_STATUSES,
RECEIVE_LOGIN_RESPONSE,
@@ -141,15 +152,81 @@ enum neg_event {
NUM_NEG_EVENTS
 };
 
+enum frame_status {
+   GOOD_FRAME,
+   GOOD_AS_FIRST_FRAME,
+   GOOD_AS_FIRST_MULTICAST_FRAME,
+   FRAME_NOT_READY,
+   FRAME_ERROR,
+};
+
+enum packet_filter {
+   /* all multicast MAC addresses */
+   PACKET_TYPE_ALL_MULTICAST,
+   /* all types of MAC addresses: multicast, unicast and broadcast */
+   PACKET_TYPE_PROMISCUOUS,
+   /* all unicast MAC addresses */
+   PACKET_TYPE_UNICAST_PROMISCUOUS,
+};
+
 enum disconnect_path_stage {
STAGE_1 = BIT(0),
STAGE_2 = BIT(1)
 };
 
+struct tbt_net_stats {
+   u64 tx_packets;
+   u64 tx_bytes;
+   u64 tx_errors;
+   u64 rx_packets;
+   u64 rx_bytes;
+   u64 rx_length_errors;
+   u64 rx_over_errors;
+   u64 rx_crc_errors;
+   u64 rx_missed_errors;
+   u64 multicast;
+};
+
+static const char tbt_net_gstrings_stats[][ETH_GSTRING_LEN] = {
+   "tx_packets",
+   "tx_bytes",
+   "tx_errors",
+   "rx_packets",
+   "rx_bytes",
+   "rx_length_errors",
+   "rx_over_errors",
+   "rx_crc_errors",
+   "rx_missed_errors",
+   "multicast",
+};
+
+struct tbt_buffer {
+   dma_addr_t dma;
+   union {
+   struct tbt_frame_header *hdr;
+   struct page *page;
+   };
+   u32 page_offset;
+};
+
+struct tbt_desc_ring {
+   /* pointer to the descriptor ring memory */
+   struct tbt_buf_desc *desc;
+   /* physical address of the descriptor ring */
+   dma_addr_t dma;
+   /* array of buffer structs */
+   struct tbt_buffer *buffers;
+   /* last descriptor that was associated with a buffer */
+   u16 last_allocated;
+   /* next descriptor to check for DD status bit */
+   u16 next_to_clean;
+};
+
 /**
 *  struct tbt_port - the basic tbt_port structure
 *  @tbt_nhi_ctxt:  context of the nhi controller.
 *  @net_dev:   networking device object.
+*  @napi:  network API
 *  @login_retry_work:  work queue for sending login requests.
 *  @login_response_work:   work queue for sending login responses.
 *  @work_struct logout_work:   work queue for sending logout requests.
@@ -165,6 +242,11 @@ enum disconnect_path_stage {
 *  @login_retry_count: counts number of login r

[PATCH v5 1/8] thunderbolt: Macro rename

2016-07-28 Thread Amir Levy
This first patch updates the registers file to
reflect that it isn't only for Cactus Ridge.
No functional change intended.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 drivers/thunderbolt/nhi_regs.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/thunderbolt/nhi_regs.h b/drivers/thunderbolt/nhi_regs.h
index 86b996c..75cf069 100644
--- a/drivers/thunderbolt/nhi_regs.h
+++ b/drivers/thunderbolt/nhi_regs.h
@@ -1,11 +1,11 @@
 /*
- * Thunderbolt Cactus Ridge driver - NHI registers
+ * Thunderbolt driver - NHI registers
  *
  * Copyright (c) 2014 Andreas Noever <andreas.noe...@gmail.com>
  */
 
-#ifndef DSL3510_REGS_H_
-#define DSL3510_REGS_H_
+#ifndef NHI_REGS_H_
+#define NHI_REGS_H_
 
 #include 
 
-- 
2.7.4



[PATCH v5 0/8] thunderbolt: Introducing Thunderbolt(TM) networking

2016-07-28 Thread Amir Levy
This is version 5 of Thunderbolt(TM) driver for non-Apple hardware.

Changes since v4:
 - Added Amir Levy as maintainer of thunderbolt/icm
 - Replaced private uuid definitions with uuid_be

These patches were pushed to GitHub where they can be reviewed more
comfortably with green/red highlighting:
https://github.com/01org/thunderbolt-software-kernel-tree

Daemon code:
https://github.com/01org/thunderbolt-software-daemon

For reference, here's a link to version 4:
[v4]:   https://lkml.org/lkml/2016/7/18/171

Amir Levy (8):
  thunderbolt: Macro rename
  thunderbolt: Updating the register definitions
  thunderbolt: Kconfig for Thunderbolt(TM) networking
  thunderbolt: Communication with the ICM (firmware)
  thunderbolt: Networking state machine
  thunderbolt: Networking transmit and receive
  thunderbolt: Networking doc
  thunderbolt: Adding maintainer entry

 Documentation/00-INDEX   |2 +
 Documentation/thunderbolt-networking.txt |  135 ++
 MAINTAINERS  |8 +-
 drivers/thunderbolt/Kconfig  |   25 +-
 drivers/thunderbolt/Makefile |3 +-
 drivers/thunderbolt/icm/Makefile |   28 +
 drivers/thunderbolt/icm/icm_nhi.c| 1641 +
 drivers/thunderbolt/icm/icm_nhi.h|   93 ++
 drivers/thunderbolt/icm/net.c| 2267 ++
 drivers/thunderbolt/icm/net.h|  270 
 drivers/thunderbolt/nhi_regs.h   |  115 +-
 11 files changed, 4578 insertions(+), 9 deletions(-)
 create mode 100644 Documentation/thunderbolt-networking.txt
 create mode 100644 drivers/thunderbolt/icm/Makefile
 create mode 100644 drivers/thunderbolt/icm/icm_nhi.c
 create mode 100644 drivers/thunderbolt/icm/icm_nhi.h
 create mode 100644 drivers/thunderbolt/icm/net.c
 create mode 100644 drivers/thunderbolt/icm/net.h

-- 
2.7.4



[PATCH v4 3/7] thunderbolt: Kconfig for Thunderbolt(TM) networking

2016-07-18 Thread Amir Levy
Updating the Kconfig Thunderbolt(TM) description.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 drivers/thunderbolt/Kconfig  | 25 +
 drivers/thunderbolt/Makefile |  2 +-
 2 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/drivers/thunderbolt/Kconfig b/drivers/thunderbolt/Kconfig
index c121acc..d34b0f5 100644
--- a/drivers/thunderbolt/Kconfig
+++ b/drivers/thunderbolt/Kconfig
@@ -1,13 +1,30 @@
-menuconfig THUNDERBOLT
-   tristate "Thunderbolt support for Apple devices"
+config THUNDERBOLT
+   tristate "Thunderbolt(TM) support"
depends on PCI
select CRC32
help
- Cactus Ridge Thunderbolt Controller driver
+ Thunderbolt(TM) Controller driver
+
+if THUNDERBOLT
+
+config THUNDERBOLT_APPLE
+   tristate "Apple hardware support"
+   help
  This driver is required if you want to hotplug Thunderbolt devices on
  Apple hardware.
 
  Device chaining is currently not supported.
 
- To compile this driver a module, choose M here. The module will be
+ To compile this driver as a module, choose M here. The module will be
  called thunderbolt.
+
+config THUNDERBOLT_ICM
+   tristate "Thunderbolt(TM) Networking"
+   help
+ This driver is required if you want Thunderbolt(TM) Networking on
+ non-Apple hardware.
+
+ To compile this driver as a module, choose M here. The module will be
+ called thunderbolt_icm.
+
+endif
diff --git a/drivers/thunderbolt/Makefile b/drivers/thunderbolt/Makefile
index 5d1053c..7a85bd1 100644
--- a/drivers/thunderbolt/Makefile
+++ b/drivers/thunderbolt/Makefile
@@ -1,3 +1,3 @@
-obj-${CONFIG_THUNDERBOLT} := thunderbolt.o
+obj-${CONFIG_THUNDERBOLT_APPLE} := thunderbolt.o
 thunderbolt-objs := nhi.o ctl.o tb.o switch.o cap.o path.o tunnel_pci.o 
eeprom.o
 
-- 
2.7.4



[PATCH v4 1/7] thunderbolt: Macro rename

2016-07-18 Thread Amir Levy
This first patch updates the registers file to
reflect that it isn't only for Cactus Ridge.
No functional change intended.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 drivers/thunderbolt/nhi_regs.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/thunderbolt/nhi_regs.h b/drivers/thunderbolt/nhi_regs.h
index 86b996c..75cf069 100644
--- a/drivers/thunderbolt/nhi_regs.h
+++ b/drivers/thunderbolt/nhi_regs.h
@@ -1,11 +1,11 @@
 /*
- * Thunderbolt Cactus Ridge driver - NHI registers
+ * Thunderbolt driver - NHI registers
  *
  * Copyright (c) 2014 Andreas Noever <andreas.noe...@gmail.com>
  */
 
-#ifndef DSL3510_REGS_H_
-#define DSL3510_REGS_H_
+#ifndef NHI_REGS_H_
+#define NHI_REGS_H_
 
 #include 
 
-- 
2.7.4



[PATCH v4 4/7] thunderbolt: Communication with the ICM (firmware)

2016-07-18 Thread Amir Levy
Firmware-based (a.k.a ICM - Intel Connection Manager) controller is
used for establishing and maintaining the Thunderbolt Networking
connection. We need to be able to communicate with it.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 drivers/thunderbolt/Makefile  |1 +
 drivers/thunderbolt/icm/Makefile  |   28 +
 drivers/thunderbolt/icm/icm_nhi.c | 1343 +
 drivers/thunderbolt/icm/icm_nhi.h |   93 +++
 drivers/thunderbolt/icm/net.h |  200 ++
 5 files changed, 1665 insertions(+)
 create mode 100644 drivers/thunderbolt/icm/Makefile
 create mode 100644 drivers/thunderbolt/icm/icm_nhi.c
 create mode 100644 drivers/thunderbolt/icm/icm_nhi.h
 create mode 100644 drivers/thunderbolt/icm/net.h

diff --git a/drivers/thunderbolt/Makefile b/drivers/thunderbolt/Makefile
index 7a85bd1..b6aa6a3 100644
--- a/drivers/thunderbolt/Makefile
+++ b/drivers/thunderbolt/Makefile
@@ -1,3 +1,4 @@
 obj-${CONFIG_THUNDERBOLT_APPLE} := thunderbolt.o
 thunderbolt-objs := nhi.o ctl.o tb.o switch.o cap.o path.o tunnel_pci.o 
eeprom.o
 
+obj-${CONFIG_THUNDERBOLT_ICM} += icm/
diff --git a/drivers/thunderbolt/icm/Makefile b/drivers/thunderbolt/icm/Makefile
new file mode 100644
index 000..3adfc35
--- /dev/null
+++ b/drivers/thunderbolt/icm/Makefile
@@ -0,0 +1,28 @@
+
+#
+# Intel Thunderbolt(TM) driver
+# Copyright(c) 2014 - 2016 Intel Corporation.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms and conditions of the GNU General Public License,
+# version 2, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+# more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# The full GNU General Public License is included in this distribution in
+# the file called "COPYING".
+#
+# Contact Information:
+# Intel Thunderbolt Mailing List <thunderbolt-softw...@lists.01.org>
+# Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+#
+
+
+obj-${CONFIG_THUNDERBOLT_ICM} += thunderbolt-icm.o
+thunderbolt-icm-objs := icm_nhi.o
diff --git a/drivers/thunderbolt/icm/icm_nhi.c 
b/drivers/thunderbolt/icm/icm_nhi.c
new file mode 100644
index 000..2106dea
--- /dev/null
+++ b/drivers/thunderbolt/icm/icm_nhi.c
@@ -0,0 +1,1343 @@
+/***
+ *
+ * Intel Thunderbolt(TM) driver
+ * Copyright(c) 2014 - 2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Intel Thunderbolt Mailing List <thunderbolt-softw...@lists.01.org>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ 
**/
+
+#include 
+#include 
+#include 
+#include 
+#include "icm_nhi.h"
+#include "net.h"
+
+#define NHI_GENL_VERSION 1
+#define NHI_GENL_NAME DRV_NAME
+
+#define DEVICE_DATA(num_ports, dma_port, nvm_ver_offset, nvm_auth_on_boot,\
+   support_full_e2e) \
+   ((num_ports) | ((dma_port) << 4) | ((nvm_ver_offset) << 10) | \
+((nvm_auth_on_boot) << 22) | ((support_full_e2e) << 23))
+#define DEVICE_DATA_NUM_PORTS(device_data) ((device_data) & 0xf)
+#define DEVICE_DATA_DMA_PORT(device_data) (((device_data) >> 4) & 0x3f)
+#define DEVICE_DATA_NVM_VER_OFFSET(device_data) (((device_data) >> 10) & 0xfff)
+#define DEVICE_DATA_NVM_AUTH_ON_BOOT(device_data) (((device_data) >> 22) & 0x1)
+#define DEVICE_DATA_SUPPORT_FULL_E2E(device_data) (((device_data) >> 23) & 0x1)
+
+#define USEC_TO_256_NSECS(usec) DIV_ROUND_UP((usec) * NSEC_PER_USEC, 256)
+
+/*
+ * FW->SW responses
+ * RC = response code
+ */
+enum {
+   RC_GET_TBT_

[PATCH v4 6/7] thunderbolt: Networking transmit and receive

2016-07-18 Thread Amir Levy
Handling the transmission to second peer and receiving from it.
This includes communication with upper layer, the network stack
and configuration of Thunderbolt(TM) HW.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 drivers/thunderbolt/icm/icm_nhi.c |   15 +
 drivers/thunderbolt/icm/net.c | 1475 +
 2 files changed, 1490 insertions(+)

diff --git a/drivers/thunderbolt/icm/icm_nhi.c 
b/drivers/thunderbolt/icm/icm_nhi.c
index 1bee701..052b348 100644
--- a/drivers/thunderbolt/icm/icm_nhi.c
+++ b/drivers/thunderbolt/icm/icm_nhi.c
@@ -1056,6 +1056,7 @@ static irqreturn_t nhi_msi(int __always_unused irq, void 
*data)
 {
struct tbt_nhi_ctxt *nhi_ctxt = data;
u32 isr0, isr1, imr0, imr1;
+   int i;
 
/* clear on read */
isr0 = ioread32(nhi_ctxt->iobase + REG_RING_NOTIFY_BASE);
@@ -1078,6 +1079,20 @@ static irqreturn_t nhi_msi(int __always_unused irq, void 
*data)
 
spin_unlock(_ctxt->lock);
 
+   for (i = 0; i < nhi_ctxt->num_ports; ++i) {
+   struct net_device *net_dev =
+   nhi_ctxt->net_devices[i].net_dev;
+   if (net_dev) {
+   u8 path = PATH_FROM_PORT(nhi_ctxt->num_paths, i);
+
+   if (isr0 & REG_RING_INT_RX_PROCESSED(
+   path, nhi_ctxt->num_paths))
+   tbt_net_rx_msi(net_dev);
+   if (isr0 & REG_RING_INT_TX_PROCESSED(path))
+   tbt_net_tx_msi(net_dev);
+   }
+   }
+
if (isr0 & REG_RING_INT_RX_PROCESSED(TBT_ICM_RING_NUM,
 nhi_ctxt->num_paths))
schedule_work(_ctxt->icm_msgs_work);
diff --git a/drivers/thunderbolt/icm/net.c b/drivers/thunderbolt/icm/net.c
index 1ac0b1f..0fd24f5 100644
--- a/drivers/thunderbolt/icm/net.c
+++ b/drivers/thunderbolt/icm/net.c
@@ -134,6 +134,17 @@ struct approve_inter_domain_connection_cmd {
 
 };
 
+struct tbt_frame_header {
+   /* size of the data with the frame */
+   __le32 frame_size;
+   /* running index on the frames */
+   __le16 frame_index;
+   /* ID of the frame to match frames to specific packet */
+   __le16 frame_id;
+   /* how many frames assembles a full packet */
+   __le32 frame_count;
+};
+
 enum neg_event {
RECEIVE_LOGOUT = NUM_MEDIUM_STATUSES,
RECEIVE_LOGIN_RESPONSE,
@@ -141,15 +152,81 @@ enum neg_event {
NUM_NEG_EVENTS
 };
 
+enum frame_status {
+   GOOD_FRAME,
+   GOOD_AS_FIRST_FRAME,
+   GOOD_AS_FIRST_MULTICAST_FRAME,
+   FRAME_NOT_READY,
+   FRAME_ERROR,
+};
+
+enum packet_filter {
+   /* all multicast MAC addresses */
+   PACKET_TYPE_ALL_MULTICAST,
+   /* all types of MAC addresses: multicast, unicast and broadcast */
+   PACKET_TYPE_PROMISCUOUS,
+   /* all unicast MAC addresses */
+   PACKET_TYPE_UNICAST_PROMISCUOUS,
+};
+
 enum disconnect_path_stage {
STAGE_1 = BIT(0),
STAGE_2 = BIT(1)
 };
 
+struct tbt_net_stats {
+   u64 tx_packets;
+   u64 tx_bytes;
+   u64 tx_errors;
+   u64 rx_packets;
+   u64 rx_bytes;
+   u64 rx_length_errors;
+   u64 rx_over_errors;
+   u64 rx_crc_errors;
+   u64 rx_missed_errors;
+   u64 multicast;
+};
+
+static const char tbt_net_gstrings_stats[][ETH_GSTRING_LEN] = {
+   "tx_packets",
+   "tx_bytes",
+   "tx_errors",
+   "rx_packets",
+   "rx_bytes",
+   "rx_length_errors",
+   "rx_over_errors",
+   "rx_crc_errors",
+   "rx_missed_errors",
+   "multicast",
+};
+
+struct tbt_buffer {
+   dma_addr_t dma;
+   union {
+   struct tbt_frame_header *hdr;
+   struct page *page;
+   };
+   u32 page_offset;
+};
+
+struct tbt_desc_ring {
+   /* pointer to the descriptor ring memory */
+   struct tbt_buf_desc *desc;
+   /* physical address of the descriptor ring */
+   dma_addr_t dma;
+   /* array of buffer structs */
+   struct tbt_buffer *buffers;
+   /* last descriptor that was associated with a buffer */
+   u16 last_allocated;
+   /* next descriptor to check for DD status bit */
+   u16 next_to_clean;
+};
+
 /**
 *  struct tbt_port - the basic tbt_port structure
 *  @tbt_nhi_ctxt:  context of the nhi controller.
 *  @net_dev:   networking device object.
+*  @napi:  network API
 *  @login_retry_work:  work queue for sending login requests.
 *  @login_response_work:   work queue for sending login responses.
 *  @work_struct logout_work:   work queue for sending logout requests.
@@ -165,6 +242,11 @@ enum disconnect_path_stage {
 *  @login_retry_count: counts number of login r

[PATCH v4 2/7] thunderbolt: Updating the register definitions

2016-07-18 Thread Amir Levy
Adding more Thunderbolt(TM) register definitions
and some helper macros.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 drivers/thunderbolt/nhi_regs.h | 109 +
 1 file changed, 109 insertions(+)

diff --git a/drivers/thunderbolt/nhi_regs.h b/drivers/thunderbolt/nhi_regs.h
index 75cf069..b8e961f 100644
--- a/drivers/thunderbolt/nhi_regs.h
+++ b/drivers/thunderbolt/nhi_regs.h
@@ -9,6 +9,11 @@
 
 #include 
 
+#define NHI_MMIO_BAR 0
+
+#define TBT_RING_MIN_NUM_BUFFERS   2
+#define TBT_RING_MAX_FRAME_SIZE(4 * 1024)
+
 enum ring_flags {
RING_FLAG_ISOCH_ENABLE = 1 << 27, /* TX only? */
RING_FLAG_E2E_FLOW_CONTROL = 1 << 28,
@@ -39,6 +44,33 @@ struct ring_desc {
u32 time; /* write zero */
 } __packed;
 
+/**
+ * struct tbt_buf_desc - TX/RX ring buffer descriptor.
+ * This is same as struct ring_desc, but without the use of bitfields and
+ * with explicit endianity.
+ */
+struct tbt_buf_desc {
+   __le64 phys;
+   __le32 attributes;
+   __le32 time;
+};
+
+#define DESC_ATTR_LEN_SHIFT0
+#define DESC_ATTR_LEN_MASK GENMASK(11, DESC_ATTR_LEN_SHIFT)
+#define DESC_ATTR_EOF_SHIFT12
+#define DESC_ATTR_EOF_MASK GENMASK(15, DESC_ATTR_EOF_SHIFT)
+#define DESC_ATTR_SOF_SHIFT16
+#define DESC_ATTR_SOF_MASK GENMASK(19, DESC_ATTR_SOF_SHIFT)
+#define DESC_ATTR_TX_ISOCH_DMA_EN  BIT(20) /* TX */
+#define DESC_ATTR_RX_CRC_ERR   BIT(20) /* RX after use */
+#define DESC_ATTR_DESC_DONEBIT(21)
+#define DESC_ATTR_REQ_STS  BIT(22) /* TX and RX before use */
+#define DESC_ATTR_RX_BUF_OVRN_ERR  BIT(22) /* RX after use */
+#define DESC_ATTR_INT_EN   BIT(23)
+#define DESC_ATTR_OFFSET_SHIFT 24
+#define DESC_ATTR_OFFSET_MASK  GENMASK(31, DESC_ATTR_OFFSET_SHIFT)
+
+
 /* NHI registers in bar 0 */
 
 /*
@@ -60,6 +92,30 @@ struct ring_desc {
  */
 #define REG_RX_RING_BASE   0x08000
 
+#define REG_RING_STEP  16
+#define REG_RING_PHYS_LO_OFFSET0
+#define REG_RING_PHYS_HI_OFFSET4
+#define REG_RING_CONS_PROD_OFFSET  8   /* cons - RO, prod - RW */
+#define REG_RING_CONS_SHIFT0
+#define REG_RING_CONS_MASK GENMASK(15, REG_RING_CONS_SHIFT)
+#define REG_RING_PROD_SHIFT16
+#define REG_RING_PROD_MASK GENMASK(31, REG_RING_PROD_SHIFT)
+#define REG_RING_SIZE_OFFSET   12
+#define REG_RING_SIZE_SHIFT0
+#define REG_RING_SIZE_MASK GENMASK(15, REG_RING_SIZE_SHIFT)
+#define REG_RING_BUF_SIZE_SHIFT16
+#define REG_RING_BUF_SIZE_MASK GENMASK(27, REG_RING_BUF_SIZE_SHIFT)
+
+#define TBT_RING_CONS_PROD_REG(iobase, ringbase, ringnumber) \
+ ((iobase) + (ringbase) + \
+ ((ringnumber) * REG_RING_STEP) + \
+ REG_RING_CONS_PROD_OFFSET)
+
+#define TBT_REG_RING_PROD_EXTRACT(val) (((val) & REG_RING_PROD_MASK) >> \
+  REG_RING_PROD_SHIFT)
+
+#define TBT_REG_RING_CONS_EXTRACT(val) (((val) & REG_RING_CONS_MASK) >> \
+  REG_RING_CONS_SHIFT)
 /*
  * 32 bytes per entry, one entry for every hop (REG_HOP_COUNT)
  * 00: enum_ring_flags
@@ -77,6 +133,19 @@ struct ring_desc {
  * ..: unknown
  */
 #define REG_RX_OPTIONS_BASE0x29800
+#define REG_RX_OPTS_TX_E2E_HOP_ID_SHIFT12
+#define REG_RX_OPTS_TX_E2E_HOP_ID_MASK \
+   GENMASK(22, REG_RX_OPTS_TX_E2E_HOP_ID_SHIFT)
+#define REG_RX_OPTS_MASK_OFFSET4
+#define REG_RX_OPTS_MASK_EOF_SHIFT 0
+#define REG_RX_OPTS_MASK_EOF_MASK  GENMASK(15, REG_RX_OPTS_MASK_EOF_SHIFT)
+#define REG_RX_OPTS_MASK_SOF_SHIFT 16
+#define REG_RX_OPTS_MASK_SOF_MASK  GENMASK(31, REG_RX_OPTS_MASK_SOF_SHIFT)
+
+#define REG_OPTS_STEP  32
+#define REG_OPTS_E2E_ENBIT(28)
+#define REG_OPTS_RAW   BIT(30)
+#define REG_OPTS_VALID BIT(31)
 
 /*
  * three bitfields: tx, rx, rx overflow
@@ -86,6 +155,7 @@ struct ring_desc {
  */
 #define REG_RING_NOTIFY_BASE   0x37800
 #define RING_NOTIFY_REG_COUNT(nhi) ((31 + 3 * nhi->hop_count) / 32)
+#define REG_RING_NOTIFY_STEP   4
 
 /*
  * two bitfields: rx, tx
@@ -94,8 +164,47 @@ struct ring_desc {
  */
 #define REG_RING_INTERRUPT_BASE0x38200
 #define RING_INTERRUPT_REG_COUNT(nhi) ((31 + 2 * nhi->hop_count) / 32)
+#define REG_RING_INT_TX_PROCESSED(ring_num)BIT(ring_num)
+#define REG_RING_INT_RX_PROCESSED(ring_num, num_paths) BIT((ring_num) + \
+   (num_paths))
+#define RING_INT_DISABLE(base, val) iowrite32( \
+   ioread32((base) + REG_RING_INTERRUPT_BASE) & ~(val), \
+   (base) + REG_RING_IN

[PATCH v4 5/7] thunderbolt: Networking state machine

2016-07-18 Thread Amir Levy
Negotiation states that a peer goes through in order to establish
the communication with the second peer.
This includes communication with upper layer and additional
infrastructure support to communicate with the second peer through ICM.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 drivers/thunderbolt/icm/Makefile  |   2 +-
 drivers/thunderbolt/icm/icm_nhi.c | 304 ++-
 drivers/thunderbolt/icm/net.c | 801 ++
 drivers/thunderbolt/icm/net.h |  74 
 4 files changed, 1170 insertions(+), 11 deletions(-)
 create mode 100644 drivers/thunderbolt/icm/net.c

diff --git a/drivers/thunderbolt/icm/Makefile b/drivers/thunderbolt/icm/Makefile
index 3adfc35..624ee31 100644
--- a/drivers/thunderbolt/icm/Makefile
+++ b/drivers/thunderbolt/icm/Makefile
@@ -25,4 +25,4 @@
 

 
 obj-${CONFIG_THUNDERBOLT_ICM} += thunderbolt-icm.o
-thunderbolt-icm-objs := icm_nhi.o
+thunderbolt-icm-objs := icm_nhi.o net.o
diff --git a/drivers/thunderbolt/icm/icm_nhi.c 
b/drivers/thunderbolt/icm/icm_nhi.c
index 2106dea..1bee701 100644
--- a/drivers/thunderbolt/icm/icm_nhi.c
+++ b/drivers/thunderbolt/icm/icm_nhi.c
@@ -101,6 +101,12 @@ static const struct nla_policy 
nhi_genl_policy[NHI_ATTR_MAX + 1] = {
.len = TBT_ICM_RING_MAX_FRAME_SIZE },
[NHI_ATTR_MSG_FROM_ICM] = { .type = NLA_BINARY,
.len = TBT_ICM_RING_MAX_FRAME_SIZE },
+   [NHI_ATTR_LOCAL_ROUTE_STRING]   = {.len = sizeof(struct route_string)},
+   [NHI_ATTR_LOCAL_UNIQUE_ID]  = { .len = sizeof(unique_id) },
+   [NHI_ATTR_REMOTE_UNIQUE_ID] = { .len = sizeof(unique_id) },
+   [NHI_ATTR_LOCAL_DEPTH]  = { .type = NLA_U8, },
+   [NHI_ATTR_ENABLE_FULL_E2E]  = { .type = NLA_FLAG, },
+   [NHI_ATTR_MATCH_FRAME_ID]   = { .type = NLA_FLAG, },
 };
 
 /* NHI genetlink family */
@@ -542,6 +548,29 @@ int nhi_mailbox(struct tbt_nhi_ctxt *nhi_ctxt, u32 cmd, 
u32 data, bool deinit)
return 0;
 }
 
+static inline bool nhi_is_path_disconnected(u32 cmd, u8 num_ports)
+{
+   return (cmd >= DISCONNECT_PORT_A_INTER_DOMAIN_PATH &&
+   cmd < (DISCONNECT_PORT_A_INTER_DOMAIN_PATH + num_ports));
+}
+
+static int nhi_mailbox_disconn_path(struct tbt_nhi_ctxt *nhi_ctxt, u32 cmd)
+   __releases(_list_rwsem)
+{
+   struct port_net_dev *port;
+   u32 port_num = cmd - DISCONNECT_PORT_A_INTER_DOMAIN_PATH;
+
+   port = &(nhi_ctxt->net_devices[port_num]);
+   mutex_lock(>state_mutex);
+
+   up_read(_list_rwsem);
+   port->medium_sts = MEDIUM_READY_FOR_APPROVAL;
+   if (port->net_dev)
+   negotiation_events(port->net_dev, MEDIUM_DISCONNECTED);
+   mutex_unlock(>state_mutex);
+   return  0;
+}
+
 static int nhi_mailbox_generic(struct tbt_nhi_ctxt *nhi_ctxt, u32 mb_cmd)
__releases(_list_rwsem)
 {
@@ -590,13 +619,93 @@ static int nhi_genl_mailbox(__always_unused struct 
sk_buff *u_skb,
down_read(_list_rwsem);
 
nhi_ctxt = nhi_search_ctxt(*(u32 *)info->userhdr);
-   if (nhi_ctxt && !nhi_ctxt->d0_exit)
-   return nhi_mailbox_generic(nhi_ctxt, mb_cmd);
+   if (nhi_ctxt && !nhi_ctxt->d0_exit) {
+
+   /* rwsem is released later by the below functions */
+   if (nhi_is_path_disconnected(cmd, nhi_ctxt->num_ports))
+   return nhi_mailbox_disconn_path(nhi_ctxt, cmd);
+   else
+   return nhi_mailbox_generic(nhi_ctxt, mb_cmd);
+
+   }
 
up_read(_list_rwsem);
return -ENODEV;
 }
 
+static int nhi_genl_approve_networking(__always_unused struct sk_buff *u_skb,
+  struct genl_info *info)
+{
+   struct tbt_nhi_ctxt *nhi_ctxt;
+   struct route_string *route_str;
+   int res = -ENODEV;
+   u8 port_num;
+
+   if (!info || !info->userhdr || !info->attrs ||
+   !info->attrs[NHI_ATTR_LOCAL_ROUTE_STRING] ||
+   !info->attrs[NHI_ATTR_LOCAL_UNIQUE_ID] ||
+   !info->attrs[NHI_ATTR_REMOTE_UNIQUE_ID] ||
+   !info->attrs[NHI_ATTR_LOCAL_DEPTH])
+   return -EINVAL;
+
+   /*
+* route_str is an unique topological address
+* used for approving remote controller
+*/
+   route_str = nla_data(info->attrs[NHI_ATTR_LOCAL_ROUTE_STRING]);
+   /* extracts the port we're connected to */
+   port_num = PORT_NUM_FROM_LINK(L0_PORT_NUM(route_str->lo));
+
+   down_read(_list_rwsem);
+
+   nhi_ctxt = nhi_search_ctxt(*(u32 *)info->userhdr);
+   if (nhi_ctxt && !nhi_ctxt->d0_exit) {
+   struct port_net_dev *port;
+
+   if (port_num >= nhi_ctxt->num_ports) {
+   res = -EINVAL;
+

[PATCH v4 0/7] thunderbolt: Introducing Thunderbolt(TM) networking

2016-07-18 Thread Amir Levy
This is version 4 of Thunderbolt(TM) driver for non-Apple hardware.

Changes since v3:
 - Moved new Thunderbolt device IDs from pci_ids.h to icm_nhi.h.
 - Cleanup and added some comments in code.

These patches were pushed to GitHub where they can be reviewed more
comfortably with green/red highlighting:
https://github.com/01org/thunderbolt-software-kernel-tree

Daemon code:
https://github.com/01org/thunderbolt-software-daemon

For reference, here's a link to version 3:
[v3]:   https://lkml.org/lkml/2016/7/14/311

Amir Levy (7):
  thunderbolt: Macro rename
  thunderbolt: Updating the register definitions
  thunderbolt: Kconfig for Thunderbolt(TM) networking
  thunderbolt: Communication with the ICM (firmware)
  thunderbolt: Networking state machine
  thunderbolt: Networking transmit and receive
  thunderbolt: Networking doc

 Documentation/00-INDEX   |2 +
 Documentation/thunderbolt-networking.txt |  135 ++
 drivers/thunderbolt/Kconfig  |   25 +-
 drivers/thunderbolt/Makefile |3 +-
 drivers/thunderbolt/icm/Makefile |   28 +
 drivers/thunderbolt/icm/icm_nhi.c| 1642 +
 drivers/thunderbolt/icm/icm_nhi.h|   93 ++
 drivers/thunderbolt/icm/net.c| 2276 ++
 drivers/thunderbolt/icm/net.h|  274 
 drivers/thunderbolt/nhi_regs.h   |  115 +-
 10 files changed, 4585 insertions(+), 8 deletions(-)
 create mode 100644 Documentation/thunderbolt-networking.txt
 create mode 100644 drivers/thunderbolt/icm/Makefile
 create mode 100644 drivers/thunderbolt/icm/icm_nhi.c
 create mode 100644 drivers/thunderbolt/icm/icm_nhi.h
 create mode 100644 drivers/thunderbolt/icm/net.c
 create mode 100644 drivers/thunderbolt/icm/net.h

-- 
2.7.4



[PATCH v4 7/7] thunderbolt: Networking doc

2016-07-18 Thread Amir Levy
Adding Thunderbolt(TM) networking documentation.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 Documentation/00-INDEX   |   2 +
 Documentation/thunderbolt-networking.txt | 135 +++
 2 files changed, 137 insertions(+)
 create mode 100644 Documentation/thunderbolt-networking.txt

diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX
index cd077ca..8cf1717 100644
--- a/Documentation/00-INDEX
+++ b/Documentation/00-INDEX
@@ -439,6 +439,8 @@ this_cpu_ops.txt
- List rationale behind and the way to use this_cpu operations.
 thermal/
- directory with information on managing thermal issues (CPU/temp)
+thunderbolt-networking.txt
+   - Thunderbolt(TM) Networking driver description.
 trace/
- directory with info on tracing technologies within linux
 unaligned-memory-access.txt
diff --git a/Documentation/thunderbolt-networking.txt 
b/Documentation/thunderbolt-networking.txt
new file mode 100644
index 000..b7714cf
--- /dev/null
+++ b/Documentation/thunderbolt-networking.txt
@@ -0,0 +1,135 @@
+Intel Thunderbolt(TM) Linux driver
+==
+
+Copyright(c) 2013 - 2016 Intel Corporation.
+
+Contact Information:
+Intel Thunderbolt mailing list <thunderbolt-softw...@lists.01.org>
+Edited by Michael Jamet <michael.ja...@intel.com>
+
+Overview
+
+
+Thunderbolt(TM) Networking mode is introduced with this driver.
+This kernel code creates an ethernet device utilized in computer to computer
+communication over a Thunderbolt cable.
+This driver has been added on the top of the existing thunderbolt driver
+for systems with firwmare (FW) based Thunderbolt controllers supporting
+Thunderbolt Networking.
+
+Files
+=
+
+- icm_nhi.c/h: These files allow communication with the FW (a.k.a ICM) based 
controller.
+   In addition, they create an interface for netlink communication 
with
+   a user space daemon.
+
+- net.c/net.h: These files implement the 'eth' interface for the 
Thunderbolt(TM)
+   networking.
+
+Interface to user space
+===
+
+The interface to the user space module is implemented through a Generic 
Netlink.
+In order to be accessed by the user space module, both kernel and user space
+modules have to register with the same GENL_NAME. In our case, this is
+simply "thunderbolt".
+The registration is done at driver initialization time for all instances of
+the Thunderbolt controllers.
+The communication is then carried through pre-defined Thunderbolt messages.
+Each specific message has a callback function that is called when
+the related message is received.
+
+The messages are defined as follows:
+* NHI_CMD_UNSPEC: Not used.
+* NHI_CMD_SUBSCRIBE: Subscription request from daemon to driver to open the
+  communication channel.
+* NHI_CMD_UNSUBSCRIBE: Request from daemon to driver to unsubscribe
+  to close communication channel.
+* NHI_CMD_QUERY_INFORMATION: Request information from the driver such as
+  driver version, FW version offset, number of ports in the controller
+  and DMA port.
+* NHI_CMD_MSG_TO_ICM: Message from user space module to FW.
+* NHI_CMD_MSG_FROM_ICM: Response from FW to user space module.
+* NHI_CMD_MAILBOX: Message that uses mailbox mechanism such as FW policy
+  changes or disconnect path.
+* NHI_CMD_APPROVE_TBT_NETWORKING: Request from user space
+  module to FW to establish path.
+* NHI_CMD_ICM_IN_SAFE_MODE: Indication that the FW has entered safe mode.
+
+Communication with ICM (Firmware)
+=
+
+The communication with ICM is principally achieved through
+a DMA mechanism on Ring 0.
+The driver allocates a shared memory that is physically mapped onto
+the DMA physical space at Ring 0.
+
+Interrupts
+==
+
+Thunderbolt relies on MSI-X interrupts.
+The MSI-X vector is allocated as follows:
+ICM
+ - Tx: MSI-X vector index 0
+ - Rx: MSI-X vector index 1
+
+Port 0
+ - Tx: MSI-X vector index 2
+ - Rx: MSI-X vector index 3
+
+Port 1
+ - Tx: MSI-X vector index 4
+ - Rx: MSI-X vector index 5
+
+ICM interrupts are used for communication with ICM only.
+Port 0 and Port 1 interrupts are used for Thunderbolt Networking
+communications.
+In case MSI-X is not available, the driver requests to enable MSI only.
+
+Mutexes, semaphores and spinlocks
+=
+
+The driver should be able to operate in an environment where hardware
+is asynchronously accessed by multiple entities such as netlink,
+multiple controllers etc.
+
+* send_sem: This semaphore enforces unique sender (one sender at a time)
+  to avoid wrong impairing with responses. FW may process one message
+  at the time.
+* d0_exit_send_mutex: This mutex protects D0 exit (D3) situation
+  to avoid continuing to send messages to FW.
+* d0_exit_mailbox_mutex: This mutex protects D0 exit (D3) situation to
+  avoid continuing to send commands to mailbox.
+* mailbo

[PATCH v3 2/8] thunderbolt: Updating device IDs

2016-07-14 Thread Amir Levy
Adding the new Thunderbolt(TM) device IDs to the list.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 include/linux/pci_ids.h | 44 ++--
 1 file changed, 26 insertions(+), 18 deletions(-)

diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index c58752f..2d4cc50 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2604,24 +2604,32 @@
 #define PCI_DEVICE_ID_INTEL_82441  0x1237
 #define PCI_DEVICE_ID_INTEL_82380FB0x124b
 #define PCI_DEVICE_ID_INTEL_82439  0x1250
-#define PCI_DEVICE_ID_INTEL_LIGHT_RIDGE 0x1513 /* Tbt 1 Gen 1 */
-#define PCI_DEVICE_ID_INTEL_EAGLE_RIDGE 0x151a
-#define PCI_DEVICE_ID_INTEL_LIGHT_PEAK  0x151b
-#define PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_4C 0x1547 /* Tbt 1 Gen 2 */
-#define PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_2C 0x1548
-#define PCI_DEVICE_ID_INTEL_PORT_RIDGE  0x1549
-#define PCI_DEVICE_ID_INTEL_REDWOOD_RIDGE_2C_NHI0x1566 /* Tbt 1 Gen 3 */
-#define PCI_DEVICE_ID_INTEL_REDWOOD_RIDGE_2C_BRIDGE 0x1567
-#define PCI_DEVICE_ID_INTEL_REDWOOD_RIDGE_4C_NHI0x1568
-#define PCI_DEVICE_ID_INTEL_REDWOOD_RIDGE_4C_BRIDGE 0x1569
-#define PCI_DEVICE_ID_INTEL_FALCON_RIDGE_2C_NHI 0x156a /* Thunderbolt 2 */
-#define PCI_DEVICE_ID_INTEL_FALCON_RIDGE_2C_BRIDGE  0x156b
-#define PCI_DEVICE_ID_INTEL_FALCON_RIDGE_4C_NHI 0x156c
-#define PCI_DEVICE_ID_INTEL_FALCON_RIDGE_4C_BRIDGE  0x156d
-#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_2C_NHI 0x1575 /* Thunderbolt 3 */
-#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_2C_BRIDGE  0x1576
-#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_4C_NHI 0x1577
-#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_4C_BRIDGE  0x1578
+#define PCI_DEVICE_ID_INTEL_LIGHT_RIDGE  0x1513 /* Tbt 1 Gen 1 */
+#define PCI_DEVICE_ID_INTEL_EAGLE_RIDGE  0x151a
+#define PCI_DEVICE_ID_INTEL_LIGHT_PEAK   0x151b
+#define PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_4C  0x1547 /* Tbt 1 Gen 2 */
+#define PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_2C  0x1548
+#define PCI_DEVICE_ID_INTEL_PORT_RIDGE   0x1549
+#define PCI_DEVICE_ID_INTEL_REDWOOD_RIDGE_2C_NHI 0x1566 /* Tbt 1 Gen 3 */
+#define PCI_DEVICE_ID_INTEL_REDWOOD_RIDGE_2C_BRIDGE  0x1567
+#define PCI_DEVICE_ID_INTEL_REDWOOD_RIDGE_4C_NHI 0x1568
+#define PCI_DEVICE_ID_INTEL_REDWOOD_RIDGE_4C_BRIDGE  0x1569
+#define PCI_DEVICE_ID_INTEL_FALCON_RIDGE_2C_NHI  0x156a /* Thunderbolt 2 */
+#define PCI_DEVICE_ID_INTEL_FALCON_RIDGE_2C_BRIDGE   0x156b
+#define PCI_DEVICE_ID_INTEL_FALCON_RIDGE_4C_NHI  0x156c
+#define PCI_DEVICE_ID_INTEL_FALCON_RIDGE_4C_BRIDGE   0x156d
+#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_2C_NHI  0x1575 /* Thunderbolt 3 */
+#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_2C_BRIDGE   0x1576
+#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_4C_NHI  0x1577
+#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_4C_BRIDGE   0x1578
+#define PCI_DEVICE_ID_INTEL_WIN_RIDGE_2C_NHI 0x157d /* Tbt 2 Low Pwr */
+#define PCI_DEVICE_ID_INTEL_WIN_RIDGE_2C_BRIDGE  0x157e
+#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_LP_NHI  0x15bf /* Tbt 3 Low Pwr */
+#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_LP_BRIDGE   0x15c0
+#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_4C_NHI0x15d2 /* Thunderbolt 3 */
+#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_4C_BRIDGE 0x15d3
+#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_2C_NHI0x15d9
+#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_2C_BRIDGE 0x15da
 #define PCI_DEVICE_ID_INTEL_80960_RP   0x1960
 #define PCI_DEVICE_ID_INTEL_82840_HB   0x1a21
 #define PCI_DEVICE_ID_INTEL_82845_HB   0x1a30
-- 
2.7.4



[PATCH v3 7/8] thunderbolt: Networking transmit and receive

2016-07-14 Thread Amir Levy
Handling the transmission to second peer and receiving from it.
This includes communication with upper layer, the network stack
and configuration of Thunderbolt(TM) HW.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 drivers/thunderbolt/icm/icm_nhi.c |   15 +
 drivers/thunderbolt/icm/net.c | 1475 +
 2 files changed, 1490 insertions(+)

diff --git a/drivers/thunderbolt/icm/icm_nhi.c 
b/drivers/thunderbolt/icm/icm_nhi.c
index 060bb38..f8b0527 100644
--- a/drivers/thunderbolt/icm/icm_nhi.c
+++ b/drivers/thunderbolt/icm/icm_nhi.c
@@ -1045,6 +1045,7 @@ static irqreturn_t nhi_msi(int __always_unused irq, void 
*data)
 {
struct tbt_nhi_ctxt *nhi_ctxt = data;
u32 isr0, isr1, imr0, imr1;
+   int i;
 
/* clear on read */
isr0 = ioread32(nhi_ctxt->iobase + REG_RING_NOTIFY_BASE);
@@ -1067,6 +1068,20 @@ static irqreturn_t nhi_msi(int __always_unused irq, void 
*data)
 
spin_unlock(_ctxt->lock);
 
+   for (i = 0; i < nhi_ctxt->num_ports; ++i) {
+   struct net_device *net_dev =
+   nhi_ctxt->net_devices[i].net_dev;
+   if (net_dev) {
+   u8 path = PATH_FROM_PORT(nhi_ctxt->num_paths, i);
+
+   if (isr0 & REG_RING_INT_RX_PROCESSED(
+   path, nhi_ctxt->num_paths))
+   tbt_net_rx_msi(net_dev);
+   if (isr0 & REG_RING_INT_TX_PROCESSED(path))
+   tbt_net_tx_msi(net_dev);
+   }
+   }
+
if (isr0 & REG_RING_INT_RX_PROCESSED(TBT_ICM_RING_NUM,
 nhi_ctxt->num_paths))
schedule_work(_ctxt->icm_msgs_work);
diff --git a/drivers/thunderbolt/icm/net.c b/drivers/thunderbolt/icm/net.c
index e983dfb..77cc843 100644
--- a/drivers/thunderbolt/icm/net.c
+++ b/drivers/thunderbolt/icm/net.c
@@ -135,6 +135,17 @@ struct approve_inter_domain_connection_cmd {
 
 };
 
+struct tbt_frame_header {
+   /* size of the data with the frame */
+   __le32 frame_size;
+   /* running index on the frames */
+   __le16 frame_index;
+   /* ID of the frame to match frames to specific packet */
+   __le16 frame_id;
+   /* how many frames assembles a full packet */
+   __le32 frame_count;
+};
+
 enum neg_event {
RECEIVE_LOGOUT = NUM_MEDIUM_STATUSES,
RECEIVE_LOGIN_RESPONSE,
@@ -142,15 +153,81 @@ enum neg_event {
NUM_NEG_EVENTS
 };
 
+enum frame_status {
+   GOOD_FRAME,
+   GOOD_AS_FIRST_FRAME,
+   GOOD_AS_FIRST_MULTICAST_FRAME,
+   FRAME_NOT_READY,
+   FRAME_ERROR,
+};
+
+enum packet_filter {
+   /* all multicast MAC addresses */
+   PACKET_TYPE_ALL_MULTICAST,
+   /* all types of MAC addresses: multicast, unicast and broadcast */
+   PACKET_TYPE_PROMISCUOUS,
+   /* all unicast MAC addresses */
+   PACKET_TYPE_UNICAST_PROMISCUOUS,
+};
+
 enum disconnect_path_stage {
STAGE_1 = BIT(0),
STAGE_2 = BIT(1)
 };
 
+struct tbt_net_stats {
+   u64 tx_packets;
+   u64 tx_bytes;
+   u64 tx_errors;
+   u64 rx_packets;
+   u64 rx_bytes;
+   u64 rx_length_errors;
+   u64 rx_over_errors;
+   u64 rx_crc_errors;
+   u64 rx_missed_errors;
+   u64 multicast;
+};
+
+static const char tbt_net_gstrings_stats[][ETH_GSTRING_LEN] = {
+   "tx_packets",
+   "tx_bytes",
+   "tx_errors",
+   "rx_packets",
+   "rx_bytes",
+   "rx_length_errors",
+   "rx_over_errors",
+   "rx_crc_errors",
+   "rx_missed_errors",
+   "multicast",
+};
+
+struct tbt_buffer {
+   dma_addr_t dma;
+   union {
+   struct tbt_frame_header *hdr;
+   struct page *page;
+   };
+   u32 page_offset;
+};
+
+struct tbt_desc_ring {
+   /* pointer to the descriptor ring memory */
+   struct tbt_buf_desc *desc;
+   /* physical address of the descriptor ring */
+   dma_addr_t dma;
+   /* array of buffer structs */
+   struct tbt_buffer *buffers;
+   /* last descriptor that was associated with a buffer */
+   u16 last_allocated;
+   /* next descriptor to check for DD status bit */
+   u16 next_to_clean;
+};
+
 /**
 *  struct tbt_port - the basic tbt_port structure
 *  @tbt_nhi_ctxt:  context of the nhi controller.
 *  @net_dev:   networking device object.
+*  @napi:  network API
 *  @login_retry_work:  work queue for sending login requests.
 *  @login_response_work:   work queue for sending login responses.
 *  @work_struct logout_work:   work queue for sending logout requests.
@@ -166,6 +243,11 @@ enum disconnect_path_stage {
 *  @login_retry_count: counts number of login r

[PATCH v3 6/8] thunderbolt: Networking state machine

2016-07-14 Thread Amir Levy
Negotiation states that a peer goes through in order to establish
the communication with the second peer.
This includes communication with upper layer and additional
infrastructure support to communicate with the second peer through ICM.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 drivers/thunderbolt/icm/Makefile  |   2 +-
 drivers/thunderbolt/icm/icm_nhi.c | 304 ++-
 drivers/thunderbolt/icm/net.c | 802 ++
 drivers/thunderbolt/icm/net.h |  74 
 4 files changed, 1171 insertions(+), 11 deletions(-)
 create mode 100644 drivers/thunderbolt/icm/net.c

diff --git a/drivers/thunderbolt/icm/Makefile b/drivers/thunderbolt/icm/Makefile
index 3adfc35..624ee31 100644
--- a/drivers/thunderbolt/icm/Makefile
+++ b/drivers/thunderbolt/icm/Makefile
@@ -25,4 +25,4 @@
 

 
 obj-${CONFIG_THUNDERBOLT_ICM} += thunderbolt-icm.o
-thunderbolt-icm-objs := icm_nhi.o
+thunderbolt-icm-objs := icm_nhi.o net.o
diff --git a/drivers/thunderbolt/icm/icm_nhi.c 
b/drivers/thunderbolt/icm/icm_nhi.c
index 9d178a5..060bb38 100644
--- a/drivers/thunderbolt/icm/icm_nhi.c
+++ b/drivers/thunderbolt/icm/icm_nhi.c
@@ -101,6 +101,12 @@ static const struct nla_policy 
nhi_genl_policy[NHI_ATTR_MAX + 1] = {
.len = TBT_ICM_RING_MAX_FRAME_SIZE },
[NHI_ATTR_MSG_FROM_ICM] = { .type = NLA_BINARY,
.len = TBT_ICM_RING_MAX_FRAME_SIZE },
+   [NHI_ATTR_LOCAL_ROUTE_STRING]   = {.len = sizeof(struct route_string)},
+   [NHI_ATTR_LOCAL_UNIQUE_ID]  = { .len = sizeof(unique_id) },
+   [NHI_ATTR_REMOTE_UNIQUE_ID] = { .len = sizeof(unique_id) },
+   [NHI_ATTR_LOCAL_DEPTH]  = { .type = NLA_U8, },
+   [NHI_ATTR_ENABLE_FULL_E2E]  = { .type = NLA_FLAG, },
+   [NHI_ATTR_MATCH_FRAME_ID]   = { .type = NLA_FLAG, },
 };
 
 /* NHI genetlink family */
@@ -531,6 +537,29 @@ int nhi_mailbox(struct tbt_nhi_ctxt *nhi_ctxt, u32 cmd, 
u32 data, bool deinit)
return 0;
 }
 
+static inline bool nhi_is_path_disconnected(u32 cmd, u8 num_ports)
+{
+   return (cmd >= DISCONNECT_PORT_A_INTER_DOMAIN_PATH &&
+   cmd < (DISCONNECT_PORT_A_INTER_DOMAIN_PATH + num_ports));
+}
+
+static int nhi_mailbox_disconn_path(struct tbt_nhi_ctxt *nhi_ctxt, u32 cmd)
+   __releases(_list_rwsem)
+{
+   struct port_net_dev *port;
+   u32 port_num = cmd - DISCONNECT_PORT_A_INTER_DOMAIN_PATH;
+
+   port = &(nhi_ctxt->net_devices[port_num]);
+   mutex_lock(>state_mutex);
+
+   up_read(_list_rwsem);
+   port->medium_sts = MEDIUM_READY_FOR_APPROVAL;
+   if (port->net_dev)
+   negotiation_events(port->net_dev, MEDIUM_DISCONNECTED);
+   mutex_unlock(>state_mutex);
+   return  0;
+}
+
 static int nhi_mailbox_generic(struct tbt_nhi_ctxt *nhi_ctxt, u32 mb_cmd)
__releases(_list_rwsem)
 {
@@ -579,13 +608,93 @@ static int nhi_genl_mailbox(__always_unused struct 
sk_buff *u_skb,
down_read(_list_rwsem);
 
nhi_ctxt = nhi_search_ctxt(*(u32 *)info->userhdr);
-   if (nhi_ctxt && !nhi_ctxt->d0_exit)
-   return nhi_mailbox_generic(nhi_ctxt, mb_cmd);
+   if (nhi_ctxt && !nhi_ctxt->d0_exit) {
+
+   /* rwsem is released later by the below functions */
+   if (nhi_is_path_disconnected(cmd, nhi_ctxt->num_ports))
+   return nhi_mailbox_disconn_path(nhi_ctxt, cmd);
+   else
+   return nhi_mailbox_generic(nhi_ctxt, mb_cmd);
+
+   }
 
up_read(_list_rwsem);
return -ENODEV;
 }
 
+static int nhi_genl_approve_networking(__always_unused struct sk_buff *u_skb,
+  struct genl_info *info)
+{
+   struct tbt_nhi_ctxt *nhi_ctxt;
+   struct route_string *route_str;
+   int res = -ENODEV;
+   u8 port_num;
+
+   if (!info || !info->userhdr || !info->attrs ||
+   !info->attrs[NHI_ATTR_LOCAL_ROUTE_STRING] ||
+   !info->attrs[NHI_ATTR_LOCAL_UNIQUE_ID] ||
+   !info->attrs[NHI_ATTR_REMOTE_UNIQUE_ID] ||
+   !info->attrs[NHI_ATTR_LOCAL_DEPTH])
+   return -EINVAL;
+
+   /*
+* route_str is an unique topological address
+* used for approving remote controller
+*/
+   route_str = nla_data(info->attrs[NHI_ATTR_LOCAL_ROUTE_STRING]);
+   /* extracts the port we're connected to */
+   port_num = PORT_NUM_FROM_LINK(L0_PORT_NUM(route_str->lo));
+
+   down_read(_list_rwsem);
+
+   nhi_ctxt = nhi_search_ctxt(*(u32 *)info->userhdr);
+   if (nhi_ctxt && !nhi_ctxt->d0_exit) {
+   struct port_net_dev *port;
+
+   if (port_num >= nhi_ctxt->num_ports) {
+   res = -EINVAL;
+

[PATCH v3 5/8] thunderbolt: Communication with the ICM (firmware)

2016-07-14 Thread Amir Levy
Firmware-based (a.k.a ICM - Intel Connection Manager) controller is
used for establishing and maintaining the Thunderbolt Networking
connection. We need to be able to communicate with it.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 drivers/thunderbolt/Makefile  |1 +
 drivers/thunderbolt/icm/Makefile  |   28 +
 drivers/thunderbolt/icm/icm_nhi.c | 1332 +
 drivers/thunderbolt/icm/icm_nhi.h |   84 +++
 drivers/thunderbolt/icm/net.h |  200 ++
 5 files changed, 1645 insertions(+)
 create mode 100644 drivers/thunderbolt/icm/Makefile
 create mode 100644 drivers/thunderbolt/icm/icm_nhi.c
 create mode 100644 drivers/thunderbolt/icm/icm_nhi.h
 create mode 100644 drivers/thunderbolt/icm/net.h

diff --git a/drivers/thunderbolt/Makefile b/drivers/thunderbolt/Makefile
index 7a85bd1..b6aa6a3 100644
--- a/drivers/thunderbolt/Makefile
+++ b/drivers/thunderbolt/Makefile
@@ -1,3 +1,4 @@
 obj-${CONFIG_THUNDERBOLT_APPLE} := thunderbolt.o
 thunderbolt-objs := nhi.o ctl.o tb.o switch.o cap.o path.o tunnel_pci.o 
eeprom.o
 
+obj-${CONFIG_THUNDERBOLT_ICM} += icm/
diff --git a/drivers/thunderbolt/icm/Makefile b/drivers/thunderbolt/icm/Makefile
new file mode 100644
index 000..3adfc35
--- /dev/null
+++ b/drivers/thunderbolt/icm/Makefile
@@ -0,0 +1,28 @@
+
+#
+# Intel Thunderbolt(TM) driver
+# Copyright(c) 2014 - 2016 Intel Corporation.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms and conditions of the GNU General Public License,
+# version 2, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+# more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# The full GNU General Public License is included in this distribution in
+# the file called "COPYING".
+#
+# Contact Information:
+# Intel Thunderbolt Mailing List <thunderbolt-softw...@lists.01.org>
+# Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+#
+
+
+obj-${CONFIG_THUNDERBOLT_ICM} += thunderbolt-icm.o
+thunderbolt-icm-objs := icm_nhi.o
diff --git a/drivers/thunderbolt/icm/icm_nhi.c 
b/drivers/thunderbolt/icm/icm_nhi.c
new file mode 100644
index 000..9d178a5
--- /dev/null
+++ b/drivers/thunderbolt/icm/icm_nhi.c
@@ -0,0 +1,1332 @@
+/***
+ *
+ * Intel Thunderbolt(TM) driver
+ * Copyright(c) 2014 - 2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Intel Thunderbolt Mailing List <thunderbolt-softw...@lists.01.org>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ 
**/
+
+#include 
+#include 
+#include 
+#include 
+#include "icm_nhi.h"
+#include "net.h"
+
+#define NHI_GENL_VERSION 1
+#define NHI_GENL_NAME DRV_NAME
+
+#define DEVICE_DATA(num_ports, dma_port, nvm_ver_offset, nvm_auth_on_boot,\
+   support_full_e2e) \
+   ((num_ports) | ((dma_port) << 4) | ((nvm_ver_offset) << 10) | \
+((nvm_auth_on_boot) << 22) | ((support_full_e2e) << 23))
+#define DEVICE_DATA_NUM_PORTS(device_data) ((device_data) & 0xf)
+#define DEVICE_DATA_DMA_PORT(device_data) (((device_data) >> 4) & 0x3f)
+#define DEVICE_DATA_NVM_VER_OFFSET(device_data) (((device_data) >> 10) & 0xfff)
+#define DEVICE_DATA_NVM_AUTH_ON_BOOT(device_data) (((device_data) >> 22) & 0x1)
+#define DEVICE_DATA_SUPPORT_FULL_E2E(device_data) (((device_data) >> 23) & 0x1)
+
+#define USEC_TO_256_NSECS(usec) DIV_ROUND_UP((usec) * NSEC_PER_USEC, 256)
+
+/*
+ * FW->SW responses
+ * RC = response code
+ */
+enum {
+   RC_GET_TBT_

[PATCH v3 4/8] thunderbolt: Kconfig for Thunderbolt(TM) networking

2016-07-14 Thread Amir Levy
Updating the Kconfig Thunderbolt(TM) description.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 drivers/thunderbolt/Kconfig  | 25 +
 drivers/thunderbolt/Makefile |  2 +-
 2 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/drivers/thunderbolt/Kconfig b/drivers/thunderbolt/Kconfig
index c121acc..d34b0f5 100644
--- a/drivers/thunderbolt/Kconfig
+++ b/drivers/thunderbolt/Kconfig
@@ -1,13 +1,30 @@
-menuconfig THUNDERBOLT
-   tristate "Thunderbolt support for Apple devices"
+config THUNDERBOLT
+   tristate "Thunderbolt(TM) support"
depends on PCI
select CRC32
help
- Cactus Ridge Thunderbolt Controller driver
+ Thunderbolt(TM) Controller driver
+
+if THUNDERBOLT
+
+config THUNDERBOLT_APPLE
+   tristate "Apple hardware support"
+   help
  This driver is required if you want to hotplug Thunderbolt devices on
  Apple hardware.
 
  Device chaining is currently not supported.
 
- To compile this driver a module, choose M here. The module will be
+ To compile this driver as a module, choose M here. The module will be
  called thunderbolt.
+
+config THUNDERBOLT_ICM
+   tristate "Thunderbolt(TM) Networking"
+   help
+ This driver is required if you want Thunderbolt(TM) Networking on
+ non-Apple hardware.
+
+ To compile this driver as a module, choose M here. The module will be
+ called thunderbolt_icm.
+
+endif
diff --git a/drivers/thunderbolt/Makefile b/drivers/thunderbolt/Makefile
index 5d1053c..7a85bd1 100644
--- a/drivers/thunderbolt/Makefile
+++ b/drivers/thunderbolt/Makefile
@@ -1,3 +1,3 @@
-obj-${CONFIG_THUNDERBOLT} := thunderbolt.o
+obj-${CONFIG_THUNDERBOLT_APPLE} := thunderbolt.o
 thunderbolt-objs := nhi.o ctl.o tb.o switch.o cap.o path.o tunnel_pci.o 
eeprom.o
 
-- 
2.7.4



[PATCH v3 1/8] thunderbolt: Macro rename

2016-07-14 Thread Amir Levy
This first patch updates the registers file to
reflect that it isn't only for Cactus Ridge.
No functional change intended.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 drivers/thunderbolt/nhi_regs.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/thunderbolt/nhi_regs.h b/drivers/thunderbolt/nhi_regs.h
index 86b996c..75cf069 100644
--- a/drivers/thunderbolt/nhi_regs.h
+++ b/drivers/thunderbolt/nhi_regs.h
@@ -1,11 +1,11 @@
 /*
- * Thunderbolt Cactus Ridge driver - NHI registers
+ * Thunderbolt driver - NHI registers
  *
  * Copyright (c) 2014 Andreas Noever <andreas.noe...@gmail.com>
  */
 
-#ifndef DSL3510_REGS_H_
-#define DSL3510_REGS_H_
+#ifndef NHI_REGS_H_
+#define NHI_REGS_H_
 
 #include 
 
-- 
2.7.4



[PATCH v3 0/8] thunderbolt: Introducing Thunderbolt(TM) networking

2016-07-14 Thread Amir Levy
This is version 3 of Thunderbolt(TM) driver for non-Apple hardware.

Changes since v2:
 - Moved ICM code to subdirectory - thunderbolt/icm

These patches were pushed to GitHub where they can be reviewed more
comfortably with green/red highlighting:
https://github.com/01org/thunderbolt-software-kernel-tree

Daemon code:
https://github.com/01org/thunderbolt-software-daemon

For reference, here's a link to version 2:
[v2]:   https://lkml.org/lkml/2016/6/29/160

Amir Levy (8):
  thunderbolt: Macro rename
  thunderbolt: Updating device IDs
  thunderbolt: Updating the register definitions
  thunderbolt: Kconfig for Thunderbolt(TM) networking
  thunderbolt: Communication with the ICM (firmware)
  thunderbolt: Networking state machine
  thunderbolt: Networking transmit and receive
  thunderbolt: Networking doc

 Documentation/00-INDEX   |2 +
 Documentation/thunderbolt-networking.txt |  135 ++
 drivers/thunderbolt/Kconfig  |   25 +-
 drivers/thunderbolt/Makefile |3 +-
 drivers/thunderbolt/icm/Makefile |   28 +
 drivers/thunderbolt/icm/icm_nhi.c| 1631 +
 drivers/thunderbolt/icm/icm_nhi.h|   84 ++
 drivers/thunderbolt/icm/net.c| 2277 ++
 drivers/thunderbolt/icm/net.h|  274 
 drivers/thunderbolt/nhi_regs.h   |  115 +-
 include/linux/pci_ids.h  |   44 +-
 11 files changed, 4592 insertions(+), 26 deletions(-)
 create mode 100644 Documentation/thunderbolt-networking.txt
 create mode 100644 drivers/thunderbolt/icm/Makefile
 create mode 100644 drivers/thunderbolt/icm/icm_nhi.c
 create mode 100644 drivers/thunderbolt/icm/icm_nhi.h
 create mode 100644 drivers/thunderbolt/icm/net.c
 create mode 100644 drivers/thunderbolt/icm/net.h

-- 
2.7.4



[PATCH v3 8/8] thunderbolt: Networking doc

2016-07-14 Thread Amir Levy
Adding Thunderbolt(TM) networking documentation.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 Documentation/00-INDEX   |   2 +
 Documentation/thunderbolt-networking.txt | 135 +++
 2 files changed, 137 insertions(+)
 create mode 100644 Documentation/thunderbolt-networking.txt

diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX
index cd077ca..8cf1717 100644
--- a/Documentation/00-INDEX
+++ b/Documentation/00-INDEX
@@ -439,6 +439,8 @@ this_cpu_ops.txt
- List rationale behind and the way to use this_cpu operations.
 thermal/
- directory with information on managing thermal issues (CPU/temp)
+thunderbolt-networking.txt
+   - Thunderbolt(TM) Networking driver description.
 trace/
- directory with info on tracing technologies within linux
 unaligned-memory-access.txt
diff --git a/Documentation/thunderbolt-networking.txt 
b/Documentation/thunderbolt-networking.txt
new file mode 100644
index 000..b7714cf
--- /dev/null
+++ b/Documentation/thunderbolt-networking.txt
@@ -0,0 +1,135 @@
+Intel Thunderbolt(TM) Linux driver
+==
+
+Copyright(c) 2013 - 2016 Intel Corporation.
+
+Contact Information:
+Intel Thunderbolt mailing list <thunderbolt-softw...@lists.01.org>
+Edited by Michael Jamet <michael.ja...@intel.com>
+
+Overview
+
+
+Thunderbolt(TM) Networking mode is introduced with this driver.
+This kernel code creates an ethernet device utilized in computer to computer
+communication over a Thunderbolt cable.
+This driver has been added on the top of the existing thunderbolt driver
+for systems with firwmare (FW) based Thunderbolt controllers supporting
+Thunderbolt Networking.
+
+Files
+=
+
+- icm_nhi.c/h: These files allow communication with the FW (a.k.a ICM) based 
controller.
+   In addition, they create an interface for netlink communication 
with
+   a user space daemon.
+
+- net.c/net.h: These files implement the 'eth' interface for the 
Thunderbolt(TM)
+   networking.
+
+Interface to user space
+===
+
+The interface to the user space module is implemented through a Generic 
Netlink.
+In order to be accessed by the user space module, both kernel and user space
+modules have to register with the same GENL_NAME. In our case, this is
+simply "thunderbolt".
+The registration is done at driver initialization time for all instances of
+the Thunderbolt controllers.
+The communication is then carried through pre-defined Thunderbolt messages.
+Each specific message has a callback function that is called when
+the related message is received.
+
+The messages are defined as follows:
+* NHI_CMD_UNSPEC: Not used.
+* NHI_CMD_SUBSCRIBE: Subscription request from daemon to driver to open the
+  communication channel.
+* NHI_CMD_UNSUBSCRIBE: Request from daemon to driver to unsubscribe
+  to close communication channel.
+* NHI_CMD_QUERY_INFORMATION: Request information from the driver such as
+  driver version, FW version offset, number of ports in the controller
+  and DMA port.
+* NHI_CMD_MSG_TO_ICM: Message from user space module to FW.
+* NHI_CMD_MSG_FROM_ICM: Response from FW to user space module.
+* NHI_CMD_MAILBOX: Message that uses mailbox mechanism such as FW policy
+  changes or disconnect path.
+* NHI_CMD_APPROVE_TBT_NETWORKING: Request from user space
+  module to FW to establish path.
+* NHI_CMD_ICM_IN_SAFE_MODE: Indication that the FW has entered safe mode.
+
+Communication with ICM (Firmware)
+=
+
+The communication with ICM is principally achieved through
+a DMA mechanism on Ring 0.
+The driver allocates a shared memory that is physically mapped onto
+the DMA physical space at Ring 0.
+
+Interrupts
+==
+
+Thunderbolt relies on MSI-X interrupts.
+The MSI-X vector is allocated as follows:
+ICM
+ - Tx: MSI-X vector index 0
+ - Rx: MSI-X vector index 1
+
+Port 0
+ - Tx: MSI-X vector index 2
+ - Rx: MSI-X vector index 3
+
+Port 1
+ - Tx: MSI-X vector index 4
+ - Rx: MSI-X vector index 5
+
+ICM interrupts are used for communication with ICM only.
+Port 0 and Port 1 interrupts are used for Thunderbolt Networking
+communications.
+In case MSI-X is not available, the driver requests to enable MSI only.
+
+Mutexes, semaphores and spinlocks
+=
+
+The driver should be able to operate in an environment where hardware
+is asynchronously accessed by multiple entities such as netlink,
+multiple controllers etc.
+
+* send_sem: This semaphore enforces unique sender (one sender at a time)
+  to avoid wrong impairing with responses. FW may process one message
+  at the time.
+* d0_exit_send_mutex: This mutex protects D0 exit (D3) situation
+  to avoid continuing to send messages to FW.
+* d0_exit_mailbox_mutex: This mutex protects D0 exit (D3) situation to
+  avoid continuing to send commands to mailbox.
+* mailbo

[PATCH v3 3/8] thunderbolt: Updating the register definitions

2016-07-14 Thread Amir Levy
Adding more Thunderbolt(TM) register definitions
and some helper macros.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 drivers/thunderbolt/nhi_regs.h | 109 +
 1 file changed, 109 insertions(+)

diff --git a/drivers/thunderbolt/nhi_regs.h b/drivers/thunderbolt/nhi_regs.h
index 75cf069..b8e961f 100644
--- a/drivers/thunderbolt/nhi_regs.h
+++ b/drivers/thunderbolt/nhi_regs.h
@@ -9,6 +9,11 @@
 
 #include 
 
+#define NHI_MMIO_BAR 0
+
+#define TBT_RING_MIN_NUM_BUFFERS   2
+#define TBT_RING_MAX_FRAME_SIZE(4 * 1024)
+
 enum ring_flags {
RING_FLAG_ISOCH_ENABLE = 1 << 27, /* TX only? */
RING_FLAG_E2E_FLOW_CONTROL = 1 << 28,
@@ -39,6 +44,33 @@ struct ring_desc {
u32 time; /* write zero */
 } __packed;
 
+/**
+ * struct tbt_buf_desc - TX/RX ring buffer descriptor.
+ * This is same as struct ring_desc, but without the use of bitfields and
+ * with explicit endianity.
+ */
+struct tbt_buf_desc {
+   __le64 phys;
+   __le32 attributes;
+   __le32 time;
+};
+
+#define DESC_ATTR_LEN_SHIFT0
+#define DESC_ATTR_LEN_MASK GENMASK(11, DESC_ATTR_LEN_SHIFT)
+#define DESC_ATTR_EOF_SHIFT12
+#define DESC_ATTR_EOF_MASK GENMASK(15, DESC_ATTR_EOF_SHIFT)
+#define DESC_ATTR_SOF_SHIFT16
+#define DESC_ATTR_SOF_MASK GENMASK(19, DESC_ATTR_SOF_SHIFT)
+#define DESC_ATTR_TX_ISOCH_DMA_EN  BIT(20) /* TX */
+#define DESC_ATTR_RX_CRC_ERR   BIT(20) /* RX after use */
+#define DESC_ATTR_DESC_DONEBIT(21)
+#define DESC_ATTR_REQ_STS  BIT(22) /* TX and RX before use */
+#define DESC_ATTR_RX_BUF_OVRN_ERR  BIT(22) /* RX after use */
+#define DESC_ATTR_INT_EN   BIT(23)
+#define DESC_ATTR_OFFSET_SHIFT 24
+#define DESC_ATTR_OFFSET_MASK  GENMASK(31, DESC_ATTR_OFFSET_SHIFT)
+
+
 /* NHI registers in bar 0 */
 
 /*
@@ -60,6 +92,30 @@ struct ring_desc {
  */
 #define REG_RX_RING_BASE   0x08000
 
+#define REG_RING_STEP  16
+#define REG_RING_PHYS_LO_OFFSET0
+#define REG_RING_PHYS_HI_OFFSET4
+#define REG_RING_CONS_PROD_OFFSET  8   /* cons - RO, prod - RW */
+#define REG_RING_CONS_SHIFT0
+#define REG_RING_CONS_MASK GENMASK(15, REG_RING_CONS_SHIFT)
+#define REG_RING_PROD_SHIFT16
+#define REG_RING_PROD_MASK GENMASK(31, REG_RING_PROD_SHIFT)
+#define REG_RING_SIZE_OFFSET   12
+#define REG_RING_SIZE_SHIFT0
+#define REG_RING_SIZE_MASK GENMASK(15, REG_RING_SIZE_SHIFT)
+#define REG_RING_BUF_SIZE_SHIFT16
+#define REG_RING_BUF_SIZE_MASK GENMASK(27, REG_RING_BUF_SIZE_SHIFT)
+
+#define TBT_RING_CONS_PROD_REG(iobase, ringbase, ringnumber) \
+ ((iobase) + (ringbase) + \
+ ((ringnumber) * REG_RING_STEP) + \
+ REG_RING_CONS_PROD_OFFSET)
+
+#define TBT_REG_RING_PROD_EXTRACT(val) (((val) & REG_RING_PROD_MASK) >> \
+  REG_RING_PROD_SHIFT)
+
+#define TBT_REG_RING_CONS_EXTRACT(val) (((val) & REG_RING_CONS_MASK) >> \
+  REG_RING_CONS_SHIFT)
 /*
  * 32 bytes per entry, one entry for every hop (REG_HOP_COUNT)
  * 00: enum_ring_flags
@@ -77,6 +133,19 @@ struct ring_desc {
  * ..: unknown
  */
 #define REG_RX_OPTIONS_BASE0x29800
+#define REG_RX_OPTS_TX_E2E_HOP_ID_SHIFT12
+#define REG_RX_OPTS_TX_E2E_HOP_ID_MASK \
+   GENMASK(22, REG_RX_OPTS_TX_E2E_HOP_ID_SHIFT)
+#define REG_RX_OPTS_MASK_OFFSET4
+#define REG_RX_OPTS_MASK_EOF_SHIFT 0
+#define REG_RX_OPTS_MASK_EOF_MASK  GENMASK(15, REG_RX_OPTS_MASK_EOF_SHIFT)
+#define REG_RX_OPTS_MASK_SOF_SHIFT 16
+#define REG_RX_OPTS_MASK_SOF_MASK  GENMASK(31, REG_RX_OPTS_MASK_SOF_SHIFT)
+
+#define REG_OPTS_STEP  32
+#define REG_OPTS_E2E_ENBIT(28)
+#define REG_OPTS_RAW   BIT(30)
+#define REG_OPTS_VALID BIT(31)
 
 /*
  * three bitfields: tx, rx, rx overflow
@@ -86,6 +155,7 @@ struct ring_desc {
  */
 #define REG_RING_NOTIFY_BASE   0x37800
 #define RING_NOTIFY_REG_COUNT(nhi) ((31 + 3 * nhi->hop_count) / 32)
+#define REG_RING_NOTIFY_STEP   4
 
 /*
  * two bitfields: rx, tx
@@ -94,8 +164,47 @@ struct ring_desc {
  */
 #define REG_RING_INTERRUPT_BASE0x38200
 #define RING_INTERRUPT_REG_COUNT(nhi) ((31 + 2 * nhi->hop_count) / 32)
+#define REG_RING_INT_TX_PROCESSED(ring_num)BIT(ring_num)
+#define REG_RING_INT_RX_PROCESSED(ring_num, num_paths) BIT((ring_num) + \
+   (num_paths))
+#define RING_INT_DISABLE(base, val) iowrite32( \
+   ioread32((base) + REG_RING_INTERRUPT_BASE) & ~(val), \
+   (base) + REG_RING_IN

[PATCH v2 3/8] thunderbolt: Updating the register definitions

2016-06-29 Thread Amir Levy
Adding more Thunderbolt(TM) register definitions
and some helper macros.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 drivers/thunderbolt/nhi_regs.h | 109 +
 1 file changed, 109 insertions(+)

diff --git a/drivers/thunderbolt/nhi_regs.h b/drivers/thunderbolt/nhi_regs.h
index 75cf069..b8e961f 100644
--- a/drivers/thunderbolt/nhi_regs.h
+++ b/drivers/thunderbolt/nhi_regs.h
@@ -9,6 +9,11 @@
 
 #include 
 
+#define NHI_MMIO_BAR 0
+
+#define TBT_RING_MIN_NUM_BUFFERS   2
+#define TBT_RING_MAX_FRAME_SIZE(4 * 1024)
+
 enum ring_flags {
RING_FLAG_ISOCH_ENABLE = 1 << 27, /* TX only? */
RING_FLAG_E2E_FLOW_CONTROL = 1 << 28,
@@ -39,6 +44,33 @@ struct ring_desc {
u32 time; /* write zero */
 } __packed;
 
+/**
+ * struct tbt_buf_desc - TX/RX ring buffer descriptor.
+ * This is same as struct ring_desc, but without the use of bitfields and
+ * with explicit endianity.
+ */
+struct tbt_buf_desc {
+   __le64 phys;
+   __le32 attributes;
+   __le32 time;
+};
+
+#define DESC_ATTR_LEN_SHIFT0
+#define DESC_ATTR_LEN_MASK GENMASK(11, DESC_ATTR_LEN_SHIFT)
+#define DESC_ATTR_EOF_SHIFT12
+#define DESC_ATTR_EOF_MASK GENMASK(15, DESC_ATTR_EOF_SHIFT)
+#define DESC_ATTR_SOF_SHIFT16
+#define DESC_ATTR_SOF_MASK GENMASK(19, DESC_ATTR_SOF_SHIFT)
+#define DESC_ATTR_TX_ISOCH_DMA_EN  BIT(20) /* TX */
+#define DESC_ATTR_RX_CRC_ERR   BIT(20) /* RX after use */
+#define DESC_ATTR_DESC_DONEBIT(21)
+#define DESC_ATTR_REQ_STS  BIT(22) /* TX and RX before use */
+#define DESC_ATTR_RX_BUF_OVRN_ERR  BIT(22) /* RX after use */
+#define DESC_ATTR_INT_EN   BIT(23)
+#define DESC_ATTR_OFFSET_SHIFT 24
+#define DESC_ATTR_OFFSET_MASK  GENMASK(31, DESC_ATTR_OFFSET_SHIFT)
+
+
 /* NHI registers in bar 0 */
 
 /*
@@ -60,6 +92,30 @@ struct ring_desc {
  */
 #define REG_RX_RING_BASE   0x08000
 
+#define REG_RING_STEP  16
+#define REG_RING_PHYS_LO_OFFSET0
+#define REG_RING_PHYS_HI_OFFSET4
+#define REG_RING_CONS_PROD_OFFSET  8   /* cons - RO, prod - RW */
+#define REG_RING_CONS_SHIFT0
+#define REG_RING_CONS_MASK GENMASK(15, REG_RING_CONS_SHIFT)
+#define REG_RING_PROD_SHIFT16
+#define REG_RING_PROD_MASK GENMASK(31, REG_RING_PROD_SHIFT)
+#define REG_RING_SIZE_OFFSET   12
+#define REG_RING_SIZE_SHIFT0
+#define REG_RING_SIZE_MASK GENMASK(15, REG_RING_SIZE_SHIFT)
+#define REG_RING_BUF_SIZE_SHIFT16
+#define REG_RING_BUF_SIZE_MASK GENMASK(27, REG_RING_BUF_SIZE_SHIFT)
+
+#define TBT_RING_CONS_PROD_REG(iobase, ringbase, ringnumber) \
+ ((iobase) + (ringbase) + \
+ ((ringnumber) * REG_RING_STEP) + \
+ REG_RING_CONS_PROD_OFFSET)
+
+#define TBT_REG_RING_PROD_EXTRACT(val) (((val) & REG_RING_PROD_MASK) >> \
+  REG_RING_PROD_SHIFT)
+
+#define TBT_REG_RING_CONS_EXTRACT(val) (((val) & REG_RING_CONS_MASK) >> \
+  REG_RING_CONS_SHIFT)
 /*
  * 32 bytes per entry, one entry for every hop (REG_HOP_COUNT)
  * 00: enum_ring_flags
@@ -77,6 +133,19 @@ struct ring_desc {
  * ..: unknown
  */
 #define REG_RX_OPTIONS_BASE0x29800
+#define REG_RX_OPTS_TX_E2E_HOP_ID_SHIFT12
+#define REG_RX_OPTS_TX_E2E_HOP_ID_MASK \
+   GENMASK(22, REG_RX_OPTS_TX_E2E_HOP_ID_SHIFT)
+#define REG_RX_OPTS_MASK_OFFSET4
+#define REG_RX_OPTS_MASK_EOF_SHIFT 0
+#define REG_RX_OPTS_MASK_EOF_MASK  GENMASK(15, REG_RX_OPTS_MASK_EOF_SHIFT)
+#define REG_RX_OPTS_MASK_SOF_SHIFT 16
+#define REG_RX_OPTS_MASK_SOF_MASK  GENMASK(31, REG_RX_OPTS_MASK_SOF_SHIFT)
+
+#define REG_OPTS_STEP  32
+#define REG_OPTS_E2E_ENBIT(28)
+#define REG_OPTS_RAW   BIT(30)
+#define REG_OPTS_VALID BIT(31)
 
 /*
  * three bitfields: tx, rx, rx overflow
@@ -86,6 +155,7 @@ struct ring_desc {
  */
 #define REG_RING_NOTIFY_BASE   0x37800
 #define RING_NOTIFY_REG_COUNT(nhi) ((31 + 3 * nhi->hop_count) / 32)
+#define REG_RING_NOTIFY_STEP   4
 
 /*
  * two bitfields: rx, tx
@@ -94,8 +164,47 @@ struct ring_desc {
  */
 #define REG_RING_INTERRUPT_BASE0x38200
 #define RING_INTERRUPT_REG_COUNT(nhi) ((31 + 2 * nhi->hop_count) / 32)
+#define REG_RING_INT_TX_PROCESSED(ring_num)BIT(ring_num)
+#define REG_RING_INT_RX_PROCESSED(ring_num, num_paths) BIT((ring_num) + \
+   (num_paths))
+#define RING_INT_DISABLE(base, val) iowrite32( \
+   ioread32((base) + REG_RING_INTERRUPT_BASE) & ~(val), \
+   (base) + REG_RING_IN

[PATCH v2 2/8] thunderbolt: Updating device IDs

2016-06-29 Thread Amir Levy
Adding the new Thunderbolt(TM) device IDs to the list.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 include/linux/pci_ids.h | 44 ++--
 1 file changed, 26 insertions(+), 18 deletions(-)

diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index c58752f..2d4cc50 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2604,24 +2604,32 @@
 #define PCI_DEVICE_ID_INTEL_82441  0x1237
 #define PCI_DEVICE_ID_INTEL_82380FB0x124b
 #define PCI_DEVICE_ID_INTEL_82439  0x1250
-#define PCI_DEVICE_ID_INTEL_LIGHT_RIDGE 0x1513 /* Tbt 1 Gen 1 */
-#define PCI_DEVICE_ID_INTEL_EAGLE_RIDGE 0x151a
-#define PCI_DEVICE_ID_INTEL_LIGHT_PEAK  0x151b
-#define PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_4C 0x1547 /* Tbt 1 Gen 2 */
-#define PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_2C 0x1548
-#define PCI_DEVICE_ID_INTEL_PORT_RIDGE  0x1549
-#define PCI_DEVICE_ID_INTEL_REDWOOD_RIDGE_2C_NHI0x1566 /* Tbt 1 Gen 3 */
-#define PCI_DEVICE_ID_INTEL_REDWOOD_RIDGE_2C_BRIDGE 0x1567
-#define PCI_DEVICE_ID_INTEL_REDWOOD_RIDGE_4C_NHI0x1568
-#define PCI_DEVICE_ID_INTEL_REDWOOD_RIDGE_4C_BRIDGE 0x1569
-#define PCI_DEVICE_ID_INTEL_FALCON_RIDGE_2C_NHI 0x156a /* Thunderbolt 2 */
-#define PCI_DEVICE_ID_INTEL_FALCON_RIDGE_2C_BRIDGE  0x156b
-#define PCI_DEVICE_ID_INTEL_FALCON_RIDGE_4C_NHI 0x156c
-#define PCI_DEVICE_ID_INTEL_FALCON_RIDGE_4C_BRIDGE  0x156d
-#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_2C_NHI 0x1575 /* Thunderbolt 3 */
-#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_2C_BRIDGE  0x1576
-#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_4C_NHI 0x1577
-#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_4C_BRIDGE  0x1578
+#define PCI_DEVICE_ID_INTEL_LIGHT_RIDGE  0x1513 /* Tbt 1 Gen 1 */
+#define PCI_DEVICE_ID_INTEL_EAGLE_RIDGE  0x151a
+#define PCI_DEVICE_ID_INTEL_LIGHT_PEAK   0x151b
+#define PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_4C  0x1547 /* Tbt 1 Gen 2 */
+#define PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_2C  0x1548
+#define PCI_DEVICE_ID_INTEL_PORT_RIDGE   0x1549
+#define PCI_DEVICE_ID_INTEL_REDWOOD_RIDGE_2C_NHI 0x1566 /* Tbt 1 Gen 3 */
+#define PCI_DEVICE_ID_INTEL_REDWOOD_RIDGE_2C_BRIDGE  0x1567
+#define PCI_DEVICE_ID_INTEL_REDWOOD_RIDGE_4C_NHI 0x1568
+#define PCI_DEVICE_ID_INTEL_REDWOOD_RIDGE_4C_BRIDGE  0x1569
+#define PCI_DEVICE_ID_INTEL_FALCON_RIDGE_2C_NHI  0x156a /* Thunderbolt 2 */
+#define PCI_DEVICE_ID_INTEL_FALCON_RIDGE_2C_BRIDGE   0x156b
+#define PCI_DEVICE_ID_INTEL_FALCON_RIDGE_4C_NHI  0x156c
+#define PCI_DEVICE_ID_INTEL_FALCON_RIDGE_4C_BRIDGE   0x156d
+#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_2C_NHI  0x1575 /* Thunderbolt 3 */
+#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_2C_BRIDGE   0x1576
+#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_4C_NHI  0x1577
+#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_4C_BRIDGE   0x1578
+#define PCI_DEVICE_ID_INTEL_WIN_RIDGE_2C_NHI 0x157d /* Tbt 2 Low Pwr */
+#define PCI_DEVICE_ID_INTEL_WIN_RIDGE_2C_BRIDGE  0x157e
+#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_LP_NHI  0x15bf /* Tbt 3 Low Pwr */
+#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_LP_BRIDGE   0x15c0
+#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_4C_NHI0x15d2 /* Thunderbolt 3 */
+#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_4C_BRIDGE 0x15d3
+#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_2C_NHI0x15d9
+#define PCI_DEVICE_ID_INTEL_ALPINE_RIDGE_C_2C_BRIDGE 0x15da
 #define PCI_DEVICE_ID_INTEL_80960_RP   0x1960
 #define PCI_DEVICE_ID_INTEL_82840_HB   0x1a21
 #define PCI_DEVICE_ID_INTEL_82845_HB   0x1a30
-- 
2.7.4



[PATCH v2 0/8] thunderbolt: Introducing Thunderbolt(TM) networking

2016-06-29 Thread Amir Levy
This is version 2 of Thunderbolt(TM) driver for non-Apple hardware.

Changes since v1:
 - Separation to 2 modules.
 - Moved ICM specific registers definition to ICM header file.
 - Added new Thunderbolt device IDs.
 - Renamed the Thunderbolt networking documentation.
 - General cleanups

These patches were pushed to GitHub where they can be reviewed more
comfortably with green/red highlighting:
https://github.com/01org/thunderbolt-software-kernel-tree

Daemon code:
https://github.com/01org/thunderbolt-software-daemon

For reference, here's a link to version 1:
[v1]:   http://www.spinics.net/lists/linux-pci/msg51287.html

Amir Levy (8):
  thunderbolt: Macro rename
  thunderbolt: Updating device IDs
  thunderbolt: Updating the register definitions
  thunderbolt: Kconfig for Thunderbolt(TM) networking
  thunderbolt: Communication with the ICM (firmware)
  thunderbolt: Networking state machine
  thunderbolt: Networking transmit and receive
  thunderbolt: Networking doc

 Documentation/00-INDEX   |2 +
 Documentation/thunderbolt-networking.txt |  135 ++
 drivers/thunderbolt/Kconfig  |   25 +-
 drivers/thunderbolt/Makefile |4 +-
 drivers/thunderbolt/icm_nhi.c| 1631 +
 drivers/thunderbolt/icm_nhi.h|   84 ++
 drivers/thunderbolt/net.c| 2277 ++
 drivers/thunderbolt/net.h|  274 
 drivers/thunderbolt/nhi_regs.h   |  115 +-
 include/linux/pci_ids.h  |   44 +-
 10 files changed, 4565 insertions(+), 26 deletions(-)
 create mode 100644 Documentation/thunderbolt-networking.txt
 create mode 100644 drivers/thunderbolt/icm_nhi.c
 create mode 100644 drivers/thunderbolt/icm_nhi.h
 create mode 100644 drivers/thunderbolt/net.c
 create mode 100644 drivers/thunderbolt/net.h

-- 
2.7.4



[PATCH v2 1/8] thunderbolt: Macro rename

2016-06-29 Thread Amir Levy
This first patch updates the registers file to
reflect that it isn't only for Cactus Ridge.
No functional change intended.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 drivers/thunderbolt/nhi_regs.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/thunderbolt/nhi_regs.h b/drivers/thunderbolt/nhi_regs.h
index 86b996c..75cf069 100644
--- a/drivers/thunderbolt/nhi_regs.h
+++ b/drivers/thunderbolt/nhi_regs.h
@@ -1,11 +1,11 @@
 /*
- * Thunderbolt Cactus Ridge driver - NHI registers
+ * Thunderbolt driver - NHI registers
  *
  * Copyright (c) 2014 Andreas Noever <andreas.noe...@gmail.com>
  */
 
-#ifndef DSL3510_REGS_H_
-#define DSL3510_REGS_H_
+#ifndef NHI_REGS_H_
+#define NHI_REGS_H_
 
 #include 
 
-- 
2.7.4



[PATCH v2 4/8] thunderbolt: Kconfig for Thunderbolt(TM) networking

2016-06-29 Thread Amir Levy
Updating the Kconfig Thunderbolt(TM) description.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 drivers/thunderbolt/Kconfig  | 25 +
 drivers/thunderbolt/Makefile |  2 +-
 2 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/drivers/thunderbolt/Kconfig b/drivers/thunderbolt/Kconfig
index c121acc..d34b0f5 100644
--- a/drivers/thunderbolt/Kconfig
+++ b/drivers/thunderbolt/Kconfig
@@ -1,13 +1,30 @@
-menuconfig THUNDERBOLT
-   tristate "Thunderbolt support for Apple devices"
+config THUNDERBOLT
+   tristate "Thunderbolt(TM) support"
depends on PCI
select CRC32
help
- Cactus Ridge Thunderbolt Controller driver
+ Thunderbolt(TM) Controller driver
+
+if THUNDERBOLT
+
+config THUNDERBOLT_APPLE
+   tristate "Apple hardware support"
+   help
  This driver is required if you want to hotplug Thunderbolt devices on
  Apple hardware.
 
  Device chaining is currently not supported.
 
- To compile this driver a module, choose M here. The module will be
+ To compile this driver as a module, choose M here. The module will be
  called thunderbolt.
+
+config THUNDERBOLT_ICM
+   tristate "Thunderbolt(TM) Networking"
+   help
+ This driver is required if you want Thunderbolt(TM) Networking on
+ non-Apple hardware.
+
+ To compile this driver as a module, choose M here. The module will be
+ called thunderbolt_icm.
+
+endif
diff --git a/drivers/thunderbolt/Makefile b/drivers/thunderbolt/Makefile
index 5d1053c..7a85bd1 100644
--- a/drivers/thunderbolt/Makefile
+++ b/drivers/thunderbolt/Makefile
@@ -1,3 +1,3 @@
-obj-${CONFIG_THUNDERBOLT} := thunderbolt.o
+obj-${CONFIG_THUNDERBOLT_APPLE} := thunderbolt.o
 thunderbolt-objs := nhi.o ctl.o tb.o switch.o cap.o path.o tunnel_pci.o 
eeprom.o
 
-- 
2.7.4



[PATCH v2 5/8] thunderbolt: Communication with the ICM (firmware)

2016-06-29 Thread Amir Levy
Firmware-based (a.k.a ICM - Intel Connection Manager) controller is
used for establishing and maintaining the Thunderbolt Networking
connection. We need to be able to communicate with it.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 drivers/thunderbolt/Makefile  |2 +
 drivers/thunderbolt/icm_nhi.c | 1332 +
 drivers/thunderbolt/icm_nhi.h |   84 +++
 drivers/thunderbolt/net.h |  200 +++
 4 files changed, 1618 insertions(+)
 create mode 100644 drivers/thunderbolt/icm_nhi.c
 create mode 100644 drivers/thunderbolt/icm_nhi.h
 create mode 100644 drivers/thunderbolt/net.h

diff --git a/drivers/thunderbolt/Makefile b/drivers/thunderbolt/Makefile
index 7a85bd1..cc91d9a 100644
--- a/drivers/thunderbolt/Makefile
+++ b/drivers/thunderbolt/Makefile
@@ -1,3 +1,5 @@
 obj-${CONFIG_THUNDERBOLT_APPLE} := thunderbolt.o
 thunderbolt-objs := nhi.o ctl.o tb.o switch.o cap.o path.o tunnel_pci.o 
eeprom.o
 
+obj-${CONFIG_THUNDERBOLT_ICM} += thunderbolt-icm.o
+thunderbolt-icm-objs := icm_nhi.o
diff --git a/drivers/thunderbolt/icm_nhi.c b/drivers/thunderbolt/icm_nhi.c
new file mode 100644
index 000..9d178a5
--- /dev/null
+++ b/drivers/thunderbolt/icm_nhi.c
@@ -0,0 +1,1332 @@
+/***
+ *
+ * Intel Thunderbolt(TM) driver
+ * Copyright(c) 2014 - 2016 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ *
+ * Contact Information:
+ * Intel Thunderbolt Mailing List <thunderbolt-softw...@lists.01.org>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ 
**/
+
+#include 
+#include 
+#include 
+#include 
+#include "icm_nhi.h"
+#include "net.h"
+
+#define NHI_GENL_VERSION 1
+#define NHI_GENL_NAME DRV_NAME
+
+#define DEVICE_DATA(num_ports, dma_port, nvm_ver_offset, nvm_auth_on_boot,\
+   support_full_e2e) \
+   ((num_ports) | ((dma_port) << 4) | ((nvm_ver_offset) << 10) | \
+((nvm_auth_on_boot) << 22) | ((support_full_e2e) << 23))
+#define DEVICE_DATA_NUM_PORTS(device_data) ((device_data) & 0xf)
+#define DEVICE_DATA_DMA_PORT(device_data) (((device_data) >> 4) & 0x3f)
+#define DEVICE_DATA_NVM_VER_OFFSET(device_data) (((device_data) >> 10) & 0xfff)
+#define DEVICE_DATA_NVM_AUTH_ON_BOOT(device_data) (((device_data) >> 22) & 0x1)
+#define DEVICE_DATA_SUPPORT_FULL_E2E(device_data) (((device_data) >> 23) & 0x1)
+
+#define USEC_TO_256_NSECS(usec) DIV_ROUND_UP((usec) * NSEC_PER_USEC, 256)
+
+/*
+ * FW->SW responses
+ * RC = response code
+ */
+enum {
+   RC_GET_TBT_TOPOLOGY = 1,
+   RC_GET_VIDEO_RESOURCES_DATA,
+   RC_DRV_READY,
+   RC_APPROVE_PCI_CONNEXION,
+   RC_CHALLENGE_PCI_CONNEXION,
+   RC_ADD_DEVICE_AND_KEY,
+   RC_INTER_DOMAIN_PKT_SENT = 8,
+   RC_APPROVE_INTER_DOMAIN_CONNEXION = 0x10
+};
+
+/*
+ * FW->SW notifications
+ * NC = notification code
+ */
+enum {
+   NC_DEVICE_CONNECTED = 3,
+   NC_DEVICE_DISCONNECTED,
+   NC_DP_DEVICE_CONNECTED_NOT_TUNNELED,
+   NC_INTER_DOMAIN_CONNECTED,
+   NC_INTER_DOMAIN_DISCONNECTED
+};
+
+/* NHI genetlink commands */
+enum {
+   NHI_CMD_UNSPEC,
+   NHI_CMD_SUBSCRIBE,
+   NHI_CMD_UNSUBSCRIBE,
+   NHI_CMD_QUERY_INFORMATION,
+   NHI_CMD_MSG_TO_ICM,
+   NHI_CMD_MSG_FROM_ICM,
+   NHI_CMD_MAILBOX,
+   NHI_CMD_APPROVE_TBT_NETWORKING,
+   NHI_CMD_ICM_IN_SAFE_MODE,
+   __NHI_CMD_MAX,
+};
+#define NHI_CMD_MAX (__NHI_CMD_MAX - 1)
+
+/* NHI genetlink policy */
+static const struct nla_policy nhi_genl_policy[NHI_ATTR_MAX + 1] = {
+   [NHI_ATTR_DRV_VERSION]  = { .type = NLA_NUL_STRING, },
+   [NHI_ATTR_NVM_VER_OFFSET]   = { .type = NLA_U16, },
+   [NHI_ATTR_NUM_PORTS]= { .type = NLA_U8, },
+   [NHI_ATTR_DMA_PORT] = { .type = NLA_U8, },
+   [NHI_ATTR_SUPPORT_FULL_E2E] = { .type = NLA_FLAG, },
+   [NHI_ATTR_MAILBOX_CMD]  = { .type = NLA_U32, },
+   [NHI_ATTR_PDF]  = { .type = NLA_U32, },
+   [NHI_ATTR_MSG_TO_ICM]   = { .type = NLA_BINARY,
+ 

[PATCH v2 6/8] thunderbolt: Networking state machine

2016-06-29 Thread Amir Levy
Negotiation states that a peer goes through in order to establish
the communication with the second peer.
This includes communication with upper layer and additional
infrastructure support to communicate with the second peer through ICM.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 drivers/thunderbolt/Makefile  |   2 +-
 drivers/thunderbolt/icm_nhi.c | 304 +++-
 drivers/thunderbolt/net.c | 802 ++
 drivers/thunderbolt/net.h |  74 
 4 files changed, 1171 insertions(+), 11 deletions(-)
 create mode 100644 drivers/thunderbolt/net.c

diff --git a/drivers/thunderbolt/Makefile b/drivers/thunderbolt/Makefile
index cc91d9a..50c1c8b 100644
--- a/drivers/thunderbolt/Makefile
+++ b/drivers/thunderbolt/Makefile
@@ -2,4 +2,4 @@ obj-${CONFIG_THUNDERBOLT_APPLE} := thunderbolt.o
 thunderbolt-objs := nhi.o ctl.o tb.o switch.o cap.o path.o tunnel_pci.o 
eeprom.o
 
 obj-${CONFIG_THUNDERBOLT_ICM} += thunderbolt-icm.o
-thunderbolt-icm-objs := icm_nhi.o
+thunderbolt-icm-objs := icm_nhi.o net.o
diff --git a/drivers/thunderbolt/icm_nhi.c b/drivers/thunderbolt/icm_nhi.c
index 9d178a5..060bb38 100644
--- a/drivers/thunderbolt/icm_nhi.c
+++ b/drivers/thunderbolt/icm_nhi.c
@@ -101,6 +101,12 @@ static const struct nla_policy 
nhi_genl_policy[NHI_ATTR_MAX + 1] = {
.len = TBT_ICM_RING_MAX_FRAME_SIZE },
[NHI_ATTR_MSG_FROM_ICM] = { .type = NLA_BINARY,
.len = TBT_ICM_RING_MAX_FRAME_SIZE },
+   [NHI_ATTR_LOCAL_ROUTE_STRING]   = {.len = sizeof(struct route_string)},
+   [NHI_ATTR_LOCAL_UNIQUE_ID]  = { .len = sizeof(unique_id) },
+   [NHI_ATTR_REMOTE_UNIQUE_ID] = { .len = sizeof(unique_id) },
+   [NHI_ATTR_LOCAL_DEPTH]  = { .type = NLA_U8, },
+   [NHI_ATTR_ENABLE_FULL_E2E]  = { .type = NLA_FLAG, },
+   [NHI_ATTR_MATCH_FRAME_ID]   = { .type = NLA_FLAG, },
 };
 
 /* NHI genetlink family */
@@ -531,6 +537,29 @@ int nhi_mailbox(struct tbt_nhi_ctxt *nhi_ctxt, u32 cmd, 
u32 data, bool deinit)
return 0;
 }
 
+static inline bool nhi_is_path_disconnected(u32 cmd, u8 num_ports)
+{
+   return (cmd >= DISCONNECT_PORT_A_INTER_DOMAIN_PATH &&
+   cmd < (DISCONNECT_PORT_A_INTER_DOMAIN_PATH + num_ports));
+}
+
+static int nhi_mailbox_disconn_path(struct tbt_nhi_ctxt *nhi_ctxt, u32 cmd)
+   __releases(_list_rwsem)
+{
+   struct port_net_dev *port;
+   u32 port_num = cmd - DISCONNECT_PORT_A_INTER_DOMAIN_PATH;
+
+   port = &(nhi_ctxt->net_devices[port_num]);
+   mutex_lock(>state_mutex);
+
+   up_read(_list_rwsem);
+   port->medium_sts = MEDIUM_READY_FOR_APPROVAL;
+   if (port->net_dev)
+   negotiation_events(port->net_dev, MEDIUM_DISCONNECTED);
+   mutex_unlock(>state_mutex);
+   return  0;
+}
+
 static int nhi_mailbox_generic(struct tbt_nhi_ctxt *nhi_ctxt, u32 mb_cmd)
__releases(_list_rwsem)
 {
@@ -579,13 +608,93 @@ static int nhi_genl_mailbox(__always_unused struct 
sk_buff *u_skb,
down_read(_list_rwsem);
 
nhi_ctxt = nhi_search_ctxt(*(u32 *)info->userhdr);
-   if (nhi_ctxt && !nhi_ctxt->d0_exit)
-   return nhi_mailbox_generic(nhi_ctxt, mb_cmd);
+   if (nhi_ctxt && !nhi_ctxt->d0_exit) {
+
+   /* rwsem is released later by the below functions */
+   if (nhi_is_path_disconnected(cmd, nhi_ctxt->num_ports))
+   return nhi_mailbox_disconn_path(nhi_ctxt, cmd);
+   else
+   return nhi_mailbox_generic(nhi_ctxt, mb_cmd);
+
+   }
 
up_read(_list_rwsem);
return -ENODEV;
 }
 
+static int nhi_genl_approve_networking(__always_unused struct sk_buff *u_skb,
+  struct genl_info *info)
+{
+   struct tbt_nhi_ctxt *nhi_ctxt;
+   struct route_string *route_str;
+   int res = -ENODEV;
+   u8 port_num;
+
+   if (!info || !info->userhdr || !info->attrs ||
+   !info->attrs[NHI_ATTR_LOCAL_ROUTE_STRING] ||
+   !info->attrs[NHI_ATTR_LOCAL_UNIQUE_ID] ||
+   !info->attrs[NHI_ATTR_REMOTE_UNIQUE_ID] ||
+   !info->attrs[NHI_ATTR_LOCAL_DEPTH])
+   return -EINVAL;
+
+   /*
+* route_str is an unique topological address
+* used for approving remote controller
+*/
+   route_str = nla_data(info->attrs[NHI_ATTR_LOCAL_ROUTE_STRING]);
+   /* extracts the port we're connected to */
+   port_num = PORT_NUM_FROM_LINK(L0_PORT_NUM(route_str->lo));
+
+   down_read(_list_rwsem);
+
+   nhi_ctxt = nhi_search_ctxt(*(u32 *)info->userhdr);
+   if (nhi_ctxt && !nhi_ctxt->d0_exit) {
+   struct port_net_dev *port;
+
+   if (port_num >= nhi_ctxt->num_ports) {
+   res = -EINVAL;
+

[PATCH v2 7/8] thunderbolt: Networking transmit and receive

2016-06-29 Thread Amir Levy
Handling the transmission to second peer and receiving from it.
This includes communication with upper layer, the network stack
and configuration of Thunderbolt(TM) HW.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 drivers/thunderbolt/icm_nhi.c |   15 +
 drivers/thunderbolt/net.c | 1475 +
 2 files changed, 1490 insertions(+)

diff --git a/drivers/thunderbolt/icm_nhi.c b/drivers/thunderbolt/icm_nhi.c
index 060bb38..f8b0527 100644
--- a/drivers/thunderbolt/icm_nhi.c
+++ b/drivers/thunderbolt/icm_nhi.c
@@ -1045,6 +1045,7 @@ static irqreturn_t nhi_msi(int __always_unused irq, void 
*data)
 {
struct tbt_nhi_ctxt *nhi_ctxt = data;
u32 isr0, isr1, imr0, imr1;
+   int i;
 
/* clear on read */
isr0 = ioread32(nhi_ctxt->iobase + REG_RING_NOTIFY_BASE);
@@ -1067,6 +1068,20 @@ static irqreturn_t nhi_msi(int __always_unused irq, void 
*data)
 
spin_unlock(_ctxt->lock);
 
+   for (i = 0; i < nhi_ctxt->num_ports; ++i) {
+   struct net_device *net_dev =
+   nhi_ctxt->net_devices[i].net_dev;
+   if (net_dev) {
+   u8 path = PATH_FROM_PORT(nhi_ctxt->num_paths, i);
+
+   if (isr0 & REG_RING_INT_RX_PROCESSED(
+   path, nhi_ctxt->num_paths))
+   tbt_net_rx_msi(net_dev);
+   if (isr0 & REG_RING_INT_TX_PROCESSED(path))
+   tbt_net_tx_msi(net_dev);
+   }
+   }
+
if (isr0 & REG_RING_INT_RX_PROCESSED(TBT_ICM_RING_NUM,
 nhi_ctxt->num_paths))
schedule_work(_ctxt->icm_msgs_work);
diff --git a/drivers/thunderbolt/net.c b/drivers/thunderbolt/net.c
index e983dfb..108de28 100644
--- a/drivers/thunderbolt/net.c
+++ b/drivers/thunderbolt/net.c
@@ -135,6 +135,17 @@ struct approve_inter_domain_connection_cmd {
 
 };
 
+struct tbt_frame_header {
+   /* size of the data with the frame */
+   __le32 frame_size;
+   /* running index on the frames */
+   __le16 frame_index;
+   /* ID of the frame to match frames to specific packet */
+   __le16 frame_id;
+   /* how many frames assembles a full packet */
+   __le32 frame_count;
+};
+
 enum neg_event {
RECEIVE_LOGOUT = NUM_MEDIUM_STATUSES,
RECEIVE_LOGIN_RESPONSE,
@@ -142,15 +153,81 @@ enum neg_event {
NUM_NEG_EVENTS
 };
 
+enum frame_status {
+   GOOD_FRAME,
+   GOOD_AS_FIRST_FRAME,
+   GOOD_AS_FIRST_MULTICAST_FRAME,
+   FRAME_NOT_READY,
+   FRAME_ERROR,
+};
+
+enum packet_filter {
+   /* all multicast MAC addresses */
+   PACKET_TYPE_ALL_MULTICAST,
+   /* all types of MAC addresses: multicast, unicast and broadcast */
+   PACKET_TYPE_PROMISCUOUS,
+   /* all unicast MAC addresses */
+   PACKET_TYPE_UNICAST_PROMISCUOUS,
+};
+
 enum disconnect_path_stage {
STAGE_1 = BIT(0),
STAGE_2 = BIT(1)
 };
 
+struct tbt_net_stats {
+   u64 tx_packets;
+   u64 tx_bytes;
+   u64 tx_errors;
+   u64 rx_packets;
+   u64 rx_bytes;
+   u64 rx_length_errors;
+   u64 rx_over_errors;
+   u64 rx_crc_errors;
+   u64 rx_missed_errors;
+   u64 multicast;
+};
+
+static const char tbt_net_gstrings_stats[][ETH_GSTRING_LEN] = {
+   "tx_packets",
+   "tx_bytes",
+   "tx_errors",
+   "rx_packets",
+   "rx_bytes",
+   "rx_length_errors",
+   "rx_over_errors",
+   "rx_crc_errors",
+   "rx_missed_errors",
+   "multicast",
+};
+
+struct tbt_buffer {
+   dma_addr_t dma;
+   union {
+   struct tbt_frame_header *hdr;
+   struct page *page;
+   };
+   u32 page_offset;
+};
+
+struct tbt_desc_ring {
+   /* pointer to the descriptor ring memory */
+   struct tbt_buf_desc *desc;
+   /* physical address of the descriptor ring */
+   dma_addr_t dma;
+   /* array of buffer structs */
+   struct tbt_buffer *buffers;
+   /* last descriptor that was associated with a buffer */
+   u16 last_allocated;
+   /* next descriptor to check for DD status bit */
+   u16 next_to_clean;
+};
+
 /**
 *  struct tbt_port - the basic tbt_port structure
 *  @tbt_nhi_ctxt:  context of the nhi controller.
 *  @net_dev:   networking device object.
+*  @napi:  network API
 *  @login_retry_work:  work queue for sending login requests.
 *  @login_response_work:   work queue for sending login responses.
 *  @work_struct logout_work:   work queue for sending logout requests.
@@ -166,6 +243,11 @@ enum disconnect_path_stage {
 *  @login_retry_count: counts number of login retries sent.
 *  @local_depth:

[PATCH v2 8/8] thunderbolt: Networking doc

2016-06-29 Thread Amir Levy
Adding Thunderbolt(TM) networking documentation.

Signed-off-by: Amir Levy <amir.jer.l...@intel.com>
---
 Documentation/00-INDEX   |   2 +
 Documentation/thunderbolt-networking.txt | 135 +++
 2 files changed, 137 insertions(+)
 create mode 100644 Documentation/thunderbolt-networking.txt

diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX
index cd077ca..8cf1717 100644
--- a/Documentation/00-INDEX
+++ b/Documentation/00-INDEX
@@ -439,6 +439,8 @@ this_cpu_ops.txt
- List rationale behind and the way to use this_cpu operations.
 thermal/
- directory with information on managing thermal issues (CPU/temp)
+thunderbolt-networking.txt
+   - Thunderbolt(TM) Networking driver description.
 trace/
- directory with info on tracing technologies within linux
 unaligned-memory-access.txt
diff --git a/Documentation/thunderbolt-networking.txt 
b/Documentation/thunderbolt-networking.txt
new file mode 100644
index 000..b7714cf
--- /dev/null
+++ b/Documentation/thunderbolt-networking.txt
@@ -0,0 +1,135 @@
+Intel Thunderbolt(TM) Linux driver
+==
+
+Copyright(c) 2013 - 2016 Intel Corporation.
+
+Contact Information:
+Intel Thunderbolt mailing list <thunderbolt-softw...@lists.01.org>
+Edited by Michael Jamet <michael.ja...@intel.com>
+
+Overview
+
+
+Thunderbolt(TM) Networking mode is introduced with this driver.
+This kernel code creates an ethernet device utilized in computer to computer
+communication over a Thunderbolt cable.
+This driver has been added on the top of the existing thunderbolt driver
+for systems with firwmare (FW) based Thunderbolt controllers supporting
+Thunderbolt Networking.
+
+Files
+=
+
+- icm_nhi.c/h: These files allow communication with the FW (a.k.a ICM) based 
controller.
+   In addition, they create an interface for netlink communication 
with
+   a user space daemon.
+
+- net.c/net.h: These files implement the 'eth' interface for the 
Thunderbolt(TM)
+   networking.
+
+Interface to user space
+===
+
+The interface to the user space module is implemented through a Generic 
Netlink.
+In order to be accessed by the user space module, both kernel and user space
+modules have to register with the same GENL_NAME. In our case, this is
+simply "thunderbolt".
+The registration is done at driver initialization time for all instances of
+the Thunderbolt controllers.
+The communication is then carried through pre-defined Thunderbolt messages.
+Each specific message has a callback function that is called when
+the related message is received.
+
+The messages are defined as follows:
+* NHI_CMD_UNSPEC: Not used.
+* NHI_CMD_SUBSCRIBE: Subscription request from daemon to driver to open the
+  communication channel.
+* NHI_CMD_UNSUBSCRIBE: Request from daemon to driver to unsubscribe
+  to close communication channel.
+* NHI_CMD_QUERY_INFORMATION: Request information from the driver such as
+  driver version, FW version offset, number of ports in the controller
+  and DMA port.
+* NHI_CMD_MSG_TO_ICM: Message from user space module to FW.
+* NHI_CMD_MSG_FROM_ICM: Response from FW to user space module.
+* NHI_CMD_MAILBOX: Message that uses mailbox mechanism such as FW policy
+  changes or disconnect path.
+* NHI_CMD_APPROVE_TBT_NETWORKING: Request from user space
+  module to FW to establish path.
+* NHI_CMD_ICM_IN_SAFE_MODE: Indication that the FW has entered safe mode.
+
+Communication with ICM (Firmware)
+=
+
+The communication with ICM is principally achieved through
+a DMA mechanism on Ring 0.
+The driver allocates a shared memory that is physically mapped onto
+the DMA physical space at Ring 0.
+
+Interrupts
+==
+
+Thunderbolt relies on MSI-X interrupts.
+The MSI-X vector is allocated as follows:
+ICM
+ - Tx: MSI-X vector index 0
+ - Rx: MSI-X vector index 1
+
+Port 0
+ - Tx: MSI-X vector index 2
+ - Rx: MSI-X vector index 3
+
+Port 1
+ - Tx: MSI-X vector index 4
+ - Rx: MSI-X vector index 5
+
+ICM interrupts are used for communication with ICM only.
+Port 0 and Port 1 interrupts are used for Thunderbolt Networking
+communications.
+In case MSI-X is not available, the driver requests to enable MSI only.
+
+Mutexes, semaphores and spinlocks
+=
+
+The driver should be able to operate in an environment where hardware
+is asynchronously accessed by multiple entities such as netlink,
+multiple controllers etc.
+
+* send_sem: This semaphore enforces unique sender (one sender at a time)
+  to avoid wrong impairing with responses. FW may process one message
+  at the time.
+* d0_exit_send_mutex: This mutex protects D0 exit (D3) situation
+  to avoid continuing to send messages to FW.
+* d0_exit_mailbox_mutex: This mutex protects D0 exit (D3) situation to
+  avoid continuing to send commands to mailbox.
+* mailbo