RE: [PATCH v2 6/9] NTB: Add Messaging NTB API

2016-12-12 Thread Allen Hubbe
From: Serge Semin
> Some IDT NTB-capable PCIe-switches have message registers to communicate with
> peer devices. This patch adds new NTB API callback methods, which can be used
> to utilize these registers functionality:
>  ntb_msg_count(); - get number of message registers
>  ntb_msg_inbits(); - get bitfield of inbound message registers status
>  ntb_msg_outbits(); - get bitfield of outbound message registers status
>  ntb_msg_read_sts(); - read the inbound and outbound message registers status
>  ntb_msg_clear_sts(); - clear status bits of message registers
>  ntb_msg_set_mask(); - mask interrupts raised by status bits of message
> registers.
>  ntb_msg_clear_mask(); - clear interrupts mask bits of message registers
>  ntb_msg_read(midx, *pidx); - read message register with specified index,
> additionally getting peer port index which data received from
>  ntb_msg_write(midx, pidx); - write data to the specified message register
> sending it to the passed peer device connected over a pidx port
>  ntb_msg_event(); - notify driver context of a new message event
> 
> Of course there is hadrware which doesn't support Message registers, so

s/hadrware/hardware/

> this API is made optional.
> 
> Signed-off-by: Serge Semin 

Acked-by: Allen Hubbe 

> 
> ---
>  drivers/ntb/ntb.c   |  13 
>  include/linux/ntb.h | 205 
> 
>  2 files changed, 218 insertions(+)
> 
> diff --git a/drivers/ntb/ntb.c b/drivers/ntb/ntb.c
> index f6153af..06574f8 100644
> --- a/drivers/ntb/ntb.c
> +++ b/drivers/ntb/ntb.c
> @@ -193,6 +193,19 @@ void ntb_db_event(struct ntb_dev *ntb, int vector)
>  }
>  EXPORT_SYMBOL(ntb_db_event);
> 
> +void ntb_msg_event(struct ntb_dev *ntb)
> +{
> + unsigned long irqflags;
> +
> + spin_lock_irqsave(&ntb->ctx_lock, irqflags);
> + {
> + if (ntb->ctx_ops && ntb->ctx_ops->msg_event)
> + ntb->ctx_ops->msg_event(ntb->ctx);
> + }
> + spin_unlock_irqrestore(&ntb->ctx_lock, irqflags);
> +}
> +EXPORT_SYMBOL(ntb_msg_event);
> +
>  static int ntb_probe(struct device *dev)
>  {
>   struct ntb_dev *ntb;
> diff --git a/include/linux/ntb.h b/include/linux/ntb.h
> index a6bf15d..90746df 100644
> --- a/include/linux/ntb.h
> +++ b/include/linux/ntb.h
> @@ -164,10 +164,12 @@ static inline int ntb_client_ops_is_valid(const struct
> ntb_client_ops *ops)
>   * struct ntb_ctx_ops - ntb driver context operations
>   * @link_event:  See ntb_link_event().
>   * @db_event:See ntb_db_event().
> + * @msg_event:   See ntb_msg_event().
>   */
>  struct ntb_ctx_ops {
>   void (*link_event)(void *ctx);
>   void (*db_event)(void *ctx, int db_vector);
> + void (*msg_event)(void *ctx);
>  };
> 
>  static inline int ntb_ctx_ops_is_valid(const struct ntb_ctx_ops *ops)
> @@ -176,6 +178,7 @@ static inline int ntb_ctx_ops_is_valid(const struct 
> ntb_ctx_ops *ops)
>   return
>   /* ops->link_event  && */
>   /* ops->db_event&& */
> + /* ops->msg_event   && */
>   1;
>  }
> 
> @@ -220,6 +223,15 @@ static inline int ntb_ctx_ops_is_valid(const struct 
> ntb_ctx_ops *ops)
>   * @peer_spad_addr:  See ntb_peer_spad_addr().
>   * @peer_spad_read:  See ntb_peer_spad_read().
>   * @peer_spad_write: See ntb_peer_spad_write().
> + * @msg_count:   See ntb_msg_count().
> + * @msg_inbits:  See ntb_msg_inbits().
> + * @msg_outbits: See ntb_msg_outbits().
> + * @msg_read_sts:See ntb_msg_read_sts().
> + * @msg_clear_sts:   See ntb_msg_clear_sts().
> + * @msg_set_mask:See ntb_msg_set_mask().
> + * @msg_clear_mask:  See ntb_msg_clear_mask().
> + * @msg_read:See ntb_msg_read().
> + * @msg_write:   See ntb_msg_write().
>   */
>  struct ntb_dev_ops {
>   int (*port_number)(struct ntb_dev *ntb);
> @@ -282,6 +294,16 @@ struct ntb_dev_ops {
>   u32 (*peer_spad_read)(struct ntb_dev *ntb, int pidx, int sidx);
>   int (*peer_spad_write)(struct ntb_dev *ntb, int pidx, int sidx,
>  u32 val);
> +
> + int (*msg_count)(struct ntb_dev *ntb);
> + u64 (*msg_inbits)(struct ntb_dev *ntb);
> + u64 (*msg_outbits)(struct ntb_dev *ntb);
> + u64 (*msg_read_sts)(struct ntb_dev *ntb);
> + int (*msg_clear_sts)(struct ntb_dev *ntb, u64 sts_bits);
> + int (*msg_set_mask)(struct ntb_dev *ntb, u64 mask_bits);
> + int (*msg_clear_mask)(struct ntb_dev *ntb, u64 mask_bits);
> + int (*msg_read)(struct ntb_dev *ntb, int midx, int *pidx, u32 *msg);
> + int (*msg_write)(struct ntb_dev *ntb, int midx, int pidx, u32 msg);
>  };
> 
>  static inline int ntb_dev_ops_is_valid(const struct ntb_dev_ops *ops)
> @@ -329,6 +351,15 @@ static inline int ntb_dev_ops_is_valid(const struct 
> ntb_dev_ops *ops)
>   /* !ops->peer_spad_addr == !ops->spad_count && */
>   /* !ops->peer_spad_read == !ops->spa

[PATCH v2 6/9] NTB: Add Messaging NTB API

2016-12-12 Thread Serge Semin
Some IDT NTB-capable PCIe-switches have message registers to communicate with
peer devices. This patch adds new NTB API callback methods, which can be used
to utilize these registers functionality:
 ntb_msg_count(); - get number of message registers
 ntb_msg_inbits(); - get bitfield of inbound message registers status
 ntb_msg_outbits(); - get bitfield of outbound message registers status
 ntb_msg_read_sts(); - read the inbound and outbound message registers status
 ntb_msg_clear_sts(); - clear status bits of message registers
 ntb_msg_set_mask(); - mask interrupts raised by status bits of message
registers.
 ntb_msg_clear_mask(); - clear interrupts mask bits of message registers
 ntb_msg_read(midx, *pidx); - read message register with specified index,
additionally getting peer port index which data received from
 ntb_msg_write(midx, pidx); - write data to the specified message register
sending it to the passed peer device connected over a pidx port
 ntb_msg_event(); - notify driver context of a new message event

Of course there is hadrware which doesn't support Message registers, so
this API is made optional.

Signed-off-by: Serge Semin 

---
 drivers/ntb/ntb.c   |  13 
 include/linux/ntb.h | 205 
 2 files changed, 218 insertions(+)

diff --git a/drivers/ntb/ntb.c b/drivers/ntb/ntb.c
index f6153af..06574f8 100644
--- a/drivers/ntb/ntb.c
+++ b/drivers/ntb/ntb.c
@@ -193,6 +193,19 @@ void ntb_db_event(struct ntb_dev *ntb, int vector)
 }
 EXPORT_SYMBOL(ntb_db_event);
 
+void ntb_msg_event(struct ntb_dev *ntb)
+{
+   unsigned long irqflags;
+
+   spin_lock_irqsave(&ntb->ctx_lock, irqflags);
+   {
+   if (ntb->ctx_ops && ntb->ctx_ops->msg_event)
+   ntb->ctx_ops->msg_event(ntb->ctx);
+   }
+   spin_unlock_irqrestore(&ntb->ctx_lock, irqflags);
+}
+EXPORT_SYMBOL(ntb_msg_event);
+
 static int ntb_probe(struct device *dev)
 {
struct ntb_dev *ntb;
diff --git a/include/linux/ntb.h b/include/linux/ntb.h
index a6bf15d..90746df 100644
--- a/include/linux/ntb.h
+++ b/include/linux/ntb.h
@@ -164,10 +164,12 @@ static inline int ntb_client_ops_is_valid(const struct 
ntb_client_ops *ops)
  * struct ntb_ctx_ops - ntb driver context operations
  * @link_event:See ntb_link_event().
  * @db_event:  See ntb_db_event().
+ * @msg_event: See ntb_msg_event().
  */
 struct ntb_ctx_ops {
void (*link_event)(void *ctx);
void (*db_event)(void *ctx, int db_vector);
+   void (*msg_event)(void *ctx);
 };
 
 static inline int ntb_ctx_ops_is_valid(const struct ntb_ctx_ops *ops)
@@ -176,6 +178,7 @@ static inline int ntb_ctx_ops_is_valid(const struct 
ntb_ctx_ops *ops)
return
/* ops->link_event  && */
/* ops->db_event&& */
+   /* ops->msg_event   && */
1;
 }
 
@@ -220,6 +223,15 @@ static inline int ntb_ctx_ops_is_valid(const struct 
ntb_ctx_ops *ops)
  * @peer_spad_addr:See ntb_peer_spad_addr().
  * @peer_spad_read:See ntb_peer_spad_read().
  * @peer_spad_write:   See ntb_peer_spad_write().
+ * @msg_count: See ntb_msg_count().
+ * @msg_inbits:See ntb_msg_inbits().
+ * @msg_outbits:   See ntb_msg_outbits().
+ * @msg_read_sts:  See ntb_msg_read_sts().
+ * @msg_clear_sts: See ntb_msg_clear_sts().
+ * @msg_set_mask:  See ntb_msg_set_mask().
+ * @msg_clear_mask:See ntb_msg_clear_mask().
+ * @msg_read:  See ntb_msg_read().
+ * @msg_write: See ntb_msg_write().
  */
 struct ntb_dev_ops {
int (*port_number)(struct ntb_dev *ntb);
@@ -282,6 +294,16 @@ struct ntb_dev_ops {
u32 (*peer_spad_read)(struct ntb_dev *ntb, int pidx, int sidx);
int (*peer_spad_write)(struct ntb_dev *ntb, int pidx, int sidx,
   u32 val);
+
+   int (*msg_count)(struct ntb_dev *ntb);
+   u64 (*msg_inbits)(struct ntb_dev *ntb);
+   u64 (*msg_outbits)(struct ntb_dev *ntb);
+   u64 (*msg_read_sts)(struct ntb_dev *ntb);
+   int (*msg_clear_sts)(struct ntb_dev *ntb, u64 sts_bits);
+   int (*msg_set_mask)(struct ntb_dev *ntb, u64 mask_bits);
+   int (*msg_clear_mask)(struct ntb_dev *ntb, u64 mask_bits);
+   int (*msg_read)(struct ntb_dev *ntb, int midx, int *pidx, u32 *msg);
+   int (*msg_write)(struct ntb_dev *ntb, int midx, int pidx, u32 msg);
 };
 
 static inline int ntb_dev_ops_is_valid(const struct ntb_dev_ops *ops)
@@ -329,6 +351,15 @@ static inline int ntb_dev_ops_is_valid(const struct 
ntb_dev_ops *ops)
/* !ops->peer_spad_addr == !ops->spad_count && */
/* !ops->peer_spad_read == !ops->spad_count && */
!ops->peer_spad_write == !ops->spad_count &&
+
+   !ops->msg_inbits == !ops->msg_count &&
+   !ops->msg_outbits == !ops->msg_count&&
+   !ops->msg_read_sts == !ops->msg_c