]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
IB/opa_vnic: Add routing control information
authorNiranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
Tue, 26 Sep 2017 13:44:26 +0000 (06:44 -0700)
committerDoug Ledford <dledford@redhat.com>
Wed, 27 Sep 2017 15:21:57 +0000 (11:21 -0400)
Add protocol specific routing control information in the encapsulation
header as per the configuration.

Reviewed-by: Sudeep Dutt <sudeep.dutt@intel.com>
Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
Signed-off-by: Scott Franco <safranco@intel.com>
Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.c
drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.h
drivers/infiniband/ulp/opa_vnic/opa_vnic_internal.h
drivers/infiniband/ulp/opa_vnic/opa_vnic_vema_iface.c

index a72278e9cd274faae10c72c77cbaa909858f4643..4be3aef40bd2ebea81f337c93d6a4752d4c35f9c 100644 (file)
@@ -406,6 +406,42 @@ u8 opa_vnic_get_vl(struct opa_vnic_adapter *adapter, struct sk_buff *skb)
        return vl;
 }
 
+/* opa_vnic_get_rc - return the routing control */
+static u8 opa_vnic_get_rc(struct __opa_veswport_info *info,
+                         struct sk_buff *skb)
+{
+       u8 proto, rout_ctrl;
+
+       switch (vlan_get_protocol(skb)) {
+       case htons(ETH_P_IPV6):
+               proto = ipv6_hdr(skb)->nexthdr;
+               if (proto == IPPROTO_TCP)
+                       rout_ctrl = OPA_VNIC_ENCAP_RC_EXT(info->vesw.rc,
+                                                         IPV6_TCP);
+               else if (proto == IPPROTO_UDP)
+                       rout_ctrl = OPA_VNIC_ENCAP_RC_EXT(info->vesw.rc,
+                                                         IPV6_UDP);
+               else
+                       rout_ctrl = OPA_VNIC_ENCAP_RC_EXT(info->vesw.rc, IPV6);
+               break;
+       case htons(ETH_P_IP):
+               proto = ip_hdr(skb)->protocol;
+               if (proto == IPPROTO_TCP)
+                       rout_ctrl = OPA_VNIC_ENCAP_RC_EXT(info->vesw.rc,
+                                                         IPV4_TCP);
+               else if (proto == IPPROTO_UDP)
+                       rout_ctrl = OPA_VNIC_ENCAP_RC_EXT(info->vesw.rc,
+                                                         IPV4_UDP);
+               else
+                       rout_ctrl = OPA_VNIC_ENCAP_RC_EXT(info->vesw.rc, IPV4);
+               break;
+       default:
+               rout_ctrl = OPA_VNIC_ENCAP_RC_EXT(info->vesw.rc, DEFAULT);
+       }
+
+       return rout_ctrl;
+}
+
 /* opa_vnic_calc_entropy - calculate the packet entropy */
 u8 opa_vnic_calc_entropy(struct opa_vnic_adapter *adapter, struct sk_buff *skb)
 {
@@ -448,7 +484,7 @@ void opa_vnic_encap_skb(struct opa_vnic_adapter *adapter, struct sk_buff *skb)
 {
        struct __opa_veswport_info *info = &adapter->info;
        struct opa_vnic_skb_mdata *mdata;
-       u8 def_port, sc, entropy, *hdr;
+       u8 def_port, sc, rc, entropy, *hdr;
        u16 len, l4_hdr;
        u32 dlid;
 
@@ -459,6 +495,7 @@ void opa_vnic_encap_skb(struct opa_vnic_adapter *adapter, struct sk_buff *skb)
        len = opa_vnic_wire_length(skb);
        dlid = opa_vnic_get_dlid(adapter, skb, def_port);
        sc = opa_vnic_get_sc(info, skb);
+       rc = opa_vnic_get_rc(info, skb);
        l4_hdr = info->vesw.vesw_id;
 
        mdata = skb_push(skb, sizeof(*mdata));
@@ -471,6 +508,6 @@ void opa_vnic_encap_skb(struct opa_vnic_adapter *adapter, struct sk_buff *skb)
        }
 
        opa_vnic_make_header(hdr, info->vport.encap_slid, dlid, len,
-                            info->vesw.pkey, entropy, sc, 0,
+                            info->vesw.pkey, entropy, sc, rc,
                             OPA_VNIC_L4_ETHR, l4_hdr);
 }
index be45697b8e60887ebbbc9fdd4eb400f5b210ea15..e4c9bf2ef7e2137d3d40df034dad869833ace14d 100644 (file)
 #define OPA_VNIC_ETH_LINK_UP     1
 #define OPA_VNIC_ETH_LINK_DOWN   2
 
+/* routing control */
+#define OPA_VNIC_ENCAP_RC_DEFAULT   0
+#define OPA_VNIC_ENCAP_RC_IPV4      4
+#define OPA_VNIC_ENCAP_RC_IPV4_UDP  8
+#define OPA_VNIC_ENCAP_RC_IPV4_TCP  12
+#define OPA_VNIC_ENCAP_RC_IPV6      16
+#define OPA_VNIC_ENCAP_RC_IPV6_TCP  20
+#define OPA_VNIC_ENCAP_RC_IPV6_UDP  24
+
+#define OPA_VNIC_ENCAP_RC_EXT(w, b) (((w) >> OPA_VNIC_ENCAP_RC_ ## b) & 0x7)
+
 /**
  * struct opa_vesw_info - OPA vnic switch information
  * @fabric_id: 10-bit fabric id
  * @pkey: partition key
  * @u_mcast_dlid: unknown multicast dlid
  * @u_ucast_dlid: array of unknown unicast dlids
+ * @rc: routing control
  * @eth_mtu: Ethernet MTU
  */
 struct opa_vesw_info {
@@ -127,7 +139,9 @@ struct opa_vesw_info {
        __be32  u_mcast_dlid;
        __be32  u_ucast_dlid[OPA_VESW_MAX_NUM_DEF_PORT];
 
-       u8      rsvd3[60];
+       __be32  rc;
+
+       u8      rsvd3[56];
        __be16  eth_mtu;
        u8      rsvd4[2];
 } __packed;
index a90c63125671cc5ce3fb894d5eb96b723d96d946..afd95f4322620789415ad15194259945093ae452 100644 (file)
@@ -89,7 +89,9 @@ struct __opa_vesw_info {
        u32  u_mcast_dlid;
        u32  u_ucast_dlid[OPA_VESW_MAX_NUM_DEF_PORT];
 
-       u8   rsvd3[60];
+       u32  rc;
+
+       u8   rsvd3[56];
        u16  eth_mtu;
        u8   rsvd4[2];
 } __packed;
index 5553900848e3f7ab0ea4f968e9bda06657dece2d..868b5aec1537b7917eb1e6ac7d7cc3bdb09698d0 100644 (file)
@@ -176,6 +176,8 @@ void opa_vnic_get_vesw_info(struct opa_vnic_adapter *adapter,
        for (i = 0; i < OPA_VESW_MAX_NUM_DEF_PORT; i++)
                info->u_ucast_dlid[i] = cpu_to_be32(src->u_ucast_dlid[i]);
 
+       info->rc = cpu_to_be32(src->rc);
+
        memcpy(info->rsvd3, src->rsvd3, ARRAY_SIZE(src->rsvd3));
        info->eth_mtu = cpu_to_be16(src->eth_mtu);
        memcpy(info->rsvd4, src->rsvd4, ARRAY_SIZE(src->rsvd4));
@@ -208,6 +210,8 @@ void opa_vnic_set_vesw_info(struct opa_vnic_adapter *adapter,
        for (i = 0; i < OPA_VESW_MAX_NUM_DEF_PORT; i++)
                dst->u_ucast_dlid[i] = be32_to_cpu(info->u_ucast_dlid[i]);
 
+       dst->rc = be32_to_cpu(info->rc);
+
        memcpy(dst->rsvd3, info->rsvd3, ARRAY_SIZE(info->rsvd3));
        dst->eth_mtu = be16_to_cpu(info->eth_mtu);
        memcpy(dst->rsvd4, info->rsvd4, ARRAY_SIZE(info->rsvd4));