<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META content="text/html; charset=us-ascii" http-equiv=Content-Type>
<META name=GENERATOR content="MSHTML 8.00.6001.18702"></HEAD>
<BODY>
<DIV><FONT size=2 face=Arial><SPAN class=132291916-02122009>Here are the changes 
in the low level driver:</SPAN></FONT></DIV>
<DIV><FONT size=2 face=Arial><SPAN class=132291916-02122009></SPAN></FONT><FONT 
size=2 face=Arial><SPAN class=132291916-02122009></SPAN></FONT> </DIV>
<DIV><FONT size=2 face=Arial><SPAN 
class=132291916-02122009>Thanks</SPAN></FONT></DIV>
<DIV><FONT size=2 face=Arial><SPAN 
class=132291916-02122009>Tzachi</SPAN></FONT></DIV>
<DIV><FONT size=2 face=Arial><SPAN 
class=132291916-02122009></SPAN></FONT> </DIV>
<DIV><FONT size=2 face=Arial><SPAN class=132291916-02122009>Index: 
hw/mlx4/kernel/bus/core/ud_header.c<BR>===================================================================<BR>--- 
hw/mlx4/kernel/bus/core/ud_header.c (revision 2617)<BR>+++ 
hw/mlx4/kernel/bus/core/ud_header.c (working copy)<BR>@@ -62,6 +62,15 
@@<BR>  { STRUCT_FIELD_INIT(lrh, source_lid, 1, 16, 16) 
}<BR> };<BR> <BR>+static const struct ib_field eth_table[]  = 
{<BR>+ { STRUCT_FIELD_INIT(eth, dmac_h, 0, 0, 32) },<BR>+ { 
STRUCT_FIELD_INIT(eth, dmac_l, 1, 0, 16) },<BR>+ { STRUCT_FIELD_INIT(eth, 
smac_h, 1, 16,16) },<BR>+ { STRUCT_FIELD_INIT(eth, smac_l, 2, 0 ,32) 
},<BR>+ { STRUCT_FIELD_INIT(eth, type, 3, 0, 
16)}<BR>+};<BR>+<BR>+<BR> static const struct ib_field grh_table[]  = 
{<BR>  { STRUCT_FIELD_INIT(grh, ip_version, 0, 0, 4) 
},<BR>  { STRUCT_FIELD_INIT(grh, traffic_class, 0, 4, 8) },<BR>@@ 
-279,3 +288,93 @@<BR>  return 
0;<BR> }<BR> EXPORT_SYMBOL(ib_ud_header_unpack);<BR>+<BR>+/**<BR>+ * 
ib_rdmaoe_ud_header_init - Initialize UD header structure<BR>+ * 
@payload_bytes:Length of packet payload<BR>+ * @grh_present:GRH flag (if 
non-zero, GRH will be included)<BR>+ * @header:Structure to initialize<BR>+ 
*<BR>+ * ib_rdmaoe_ud_header_init() initializes the grh.ip_version, 
grh.payload_length,<BR>+ * grh.next_header, bth.opcode, bth.pad_count and<BR>+ * 
bth.transport_header_version fields of a &struct eth_ud_header given<BR>+ * 
the payload length and whether a GRH will be included.<BR>+ */<BR>+void 
ib_rdmaoe_ud_header_init(int     
      payload_bytes,<BR>+      
int          
grh_present,<BR>+      struct 
eth_ud_header    *header)<BR>+{<BR>+ int 
header_len;<BR>+<BR>+ memset(header, 0, sizeof 
*header);<BR>+<BR>+ header_len =<BR>+  sizeof 
header->eth  +<BR>+  IB_BTH_BYTES  
+<BR>+  IB_DETH_BYTES;<BR>+ if 
(grh_present)<BR>+  header_len += 
IB_GRH_BYTES;<BR>+<BR>+ header->grh_present          
= grh_present;<BR>+ if (grh_present) 
{<BR>+  header->grh.ip_version      = 
6;<BR>+  header->grh.payload_length  
=<BR>+   cpu_to_be16((IB_BTH_BYTES     
+<BR>+         
IB_DETH_BYTES    
+<BR>+         
payload_bytes    
+<BR>+         
4                
+ /* ICRC     
*/<BR>+         3) & 
~3);          /* round up 
*/<BR>+  header->grh.next_header     = 
0x1b;<BR>+ }<BR>+<BR>+ if 
(header->immediate_present)<BR>+  header->bth.opcode           

IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE;<BR>+ else<BR>+  header->bth.opcode           

IB_OPCODE_UD_SEND_ONLY;<BR>+ header->bth.pad_count                
=(u8) ((4 - payload_bytes) & 
3);<BR>+ header->bth.transport_header_version = 
0;<BR>+}<BR>+<BR>+<BR>+<BR>+/**<BR>+ * rdmaoe_ud_header_pack - Pack UD header 
struct into eth wire format<BR>+ * @header:UD header struct<BR>+ * @buf:Buffer 
to pack into<BR>+ *<BR>+ * ib_ud_header_pack() packs the UD header structure 
@header into wire<BR>+ * format in the buffer @buf.<BR>+ */<BR>+int 
rdmaoe_ud_header_pack(struct eth_ud_header 
*header,<BR>+         
void                 
*buf)<BR>+{<BR>+ int len = 0;<BR>+<BR>+ ib_pack(eth_table, 
ARRAY_SIZE(eth_table),<BR>+  &header->eth, buf);<BR>+ len 
+= IB_ETH_BYTES;<BR>+<BR>+ if (header->grh_present) 
{<BR>+  ib_pack(grh_table, 
ARRAY_SIZE(grh_table),<BR>+   &header->grh, (u8*)buf + 
len);<BR>+  len += 
IB_GRH_BYTES;<BR>+ }<BR>+<BR>+ ib_pack(bth_table, 
ARRAY_SIZE(bth_table),<BR>+  &header->bth, (u8*)buf + 
len);<BR>+ len += IB_BTH_BYTES;<BR>+<BR>+ ib_pack(deth_table, 
ARRAY_SIZE(deth_table),<BR>+  &header->deth, (u8*)buf + 
len);<BR>+ len += IB_DETH_BYTES;<BR>+<BR>+ if 
(header->immediate_present) {<BR>+  memcpy((u8*)buf + len, 
&header->immediate_data,<BR>+         
sizeof header->immediate_data);<BR>+  len += sizeof 
header->immediate_data;<BR>+ }<BR>+<BR>+ return 
len;<BR>+}<BR>+<BR>+<BR>Index: 
hw/mlx4/kernel/bus/core/verbs.c<BR>===================================================================<BR>--- 
hw/mlx4/kernel/bus/core/verbs.c (revision 2617)<BR>+++ 
hw/mlx4/kernel/bus/core/verbs.c (working copy)<BR>@@ -336,3 +336,28 
@@<BR> }<BR> EXPORT_SYMBOL(ib_destroy_ah);<BR> <BR>+enum 
rdma_transport_type<BR>+rdma_node_get_transport(enum rdma_node_type 
node_type)<BR>+{<BR>+ switch (node_type) {<BR>+ case 
RDMA_NODE_IB_CA:<BR>+ case RDMA_NODE_IB_SWITCH:<BR>+ case 
RDMA_NODE_IB_ROUTER:<BR>+  return RDMA_TRANSPORT_IB;<BR>+ case 
RDMA_NODE_RNIC:<BR>+  return 
RDMA_TRANSPORT_IWARP;<BR>+ default:<BR>+  ASSERT(FALSE);<BR>+  return 
0;<BR>+ }<BR>+}<BR>+<BR>+enum rdma_transport_type 
rdma_port_get_transport(struct ib_device 
*device,<BR>+       u8 
port_num)<BR>+{<BR>+ return device->get_port_transport 
?<BR>+  device->get_port_transport(device, port_num) 
:<BR>+  rdma_node_get_transport(device->node_type);<BR>+}<BR>+EXPORT_SYMBOL(rdma_port_get_transport);<BR>+<BR>Index: 
hw/mlx4/kernel/bus/drv/drv.c<BR>===================================================================<BR>--- 
hw/mlx4/kernel/bus/drv/drv.c (revision 2617)<BR>+++ 
hw/mlx4/kernel/bus/drv/drv.c (working copy)<BR>@@ -95,7 +95,6 
@@<BR> <BR> #endif<BR> <BR>-static 
<BR> NTSTATUS<BR> __create_child(<BR>  __in WDFDEVICE  
Device,<BR>@@ -228,13 +227,21 @@<BR> <BR>  if ( 
p_fdo->children_created )<BR>   goto 
end;<BR>- <BR>+<BR>  // eventually we'll have all information 
about children in Registry<BR>  // DriverEntry will read it into a 
Global storage and<BR>  // this routine will create all the children 
on base on this info<BR>  number_of_ib_ports = 
mlx4_count_ib_ports(mdev);<BR>  ASSERT(number_of_ib_ports >=0 
&& number_of_ib_ports <=2);<BR> <BR>+ //For now we it's 
either IB or ETH, and we always create LLE if it's 
ETH<BR>+ if((number_of_ib_ports > 0) && 
(mdev->caps.port_type[1] == MLX4_PORT_TYPE_IB) ) {<BR>+  status = 
__create_child(Device, BUS_HARDWARE_IDS, BUS_HARDWARE_DESCRIPTION, 0 
);<BR>+  if (!NT_SUCCESS(status)) {<BR>+    
MLX4_PRINT_EV(TRACE_LEVEL_ERROR, MLX4_DBG_DRV, ("__create_child (ib)failed with 
0x%x\n", status));<BR>+  }<BR>+ }<BR>+<BR>  for (i = 1; 
i <= mdev->caps.num_ports; i++) 
{<BR>         if 
(mlx4_is_enabled_port(mdev, i)) 
{<BR>             
if(mlx4_is_eth_port(mdev, i)) {<BR>@@ -869,6 +876,9 @@<BR>   goto 
err;<BR>  }<BR> <BR>+ pdev->p_wdf_device = 
Device;<BR>+ pdev->ib_hca_created = 0;<BR>+<BR>  // start the 
card<BR>  status = __start_card(Device, p_fdo );<BR>  if( 
!NT_SUCCESS( status ) ) <BR>Index: 
hw/mlx4/kernel/bus/drv/stat.c<BR>===================================================================<BR>--- 
hw/mlx4/kernel/bus/drv/stat.c (revision 2617)<BR>+++ 
hw/mlx4/kernel/bus/drv/stat.c (working copy)<BR>@@ -113,7 +113,7 
@@<BR> void st_print_mlx_header( struct mlx4_dev *mdev, struct mlx4_ib_sqp 
*sqp, struct mlx4_wqe_mlx_seg *mlx )<BR> {<BR>  if ( 
mdev->pdev->p_stat_dev->flags & MLX4_MAD_TRACE_UDH 
)<BR>- __print_ud_header( mdev, &sqp->ud_header 
);<BR>+  __print_ud_header( mdev, &sqp->hdr.ib 
);<BR>  if ( mdev->pdev->p_stat_dev->flags & 
MLX4_MAD_TRACE_WQE )<BR>   __print_mlx( mdev, mlx 
);<BR> }<BR>Index: 
hw/mlx4/kernel/bus/ib/ah.c<BR>===================================================================<BR>--- 
hw/mlx4/kernel/bus/ib/ah.c (revision 2617)<BR>+++ 
hw/mlx4/kernel/bus/ib/ah.c (working copy)<BR>@@ -32,68 +32,199 
@@<BR> <BR> #include "mlx4_ib.h"<BR> <BR>-struct ib_ah 
*mlx4_ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr)<BR>+static 
inline int rdma_link_local_addr(struct in6_addr *addr)<BR> {<BR>+ if 
(addr->s6_addr32[0] == cpu_to_be32(0xfe800000) 
&&<BR>+     addr->s6_addr32[1] == 
0)<BR>+  return 1;<BR>+ else<BR>+  return 
0;<BR>+}<BR>+<BR>+inline void rdma_get_ll_mac(struct in6_addr *addr, u8 
*mac)<BR>+{<BR>+ memcpy(mac, &addr->s6_addr[8], 
3);<BR>+ memcpy(mac + 3, &addr->s6_addr[13], 3);<BR>+ mac[0] ^= 
2;   <BR>+}<BR>+<BR>+static inline int rdma_is_multicast_addr(struct 
in6_addr *addr)<BR>+{<BR>+ return addr->s6_addr[0] == 0xff ? 1 : 
0;<BR>+}<BR>+<BR>+static inline void rdma_get_mcast_mac(struct in6_addr *addr, 
u8 *mac)<BR>+{<BR>+ int i;<BR>+<BR>+ mac[0] = 0x33;<BR>+ mac[1] = 
0x33;<BR>+ for (i = 2; i < 6; ++i)<BR>+  mac[i] = 
addr->s6_addr[i + 10];<BR>+<BR>+}<BR>+<BR>+int mlx4_ib_resolve_grh(struct 
mlx4_ib_dev *dev, const struct ib_ah_attr *ah_attr,<BR>+   u8 
*mac, int *is_mcast)<BR>+{<BR>+ int err = 0;<BR>+ struct sockaddr_in6 
dst;<BR>+<BR>+ UNREFERENCED_PARAMETER(dev);<BR>+<BR>+ *is_mcast = 
0;<BR>+ memcpy(dst.sin6_addr.s6_addr, ah_attr->grh.dgid.raw, 
sizeof(ah_attr->grh.dgid.raw));<BR>+<BR>+ if 
(rdma_link_local_addr(&dst.sin6_addr))<BR>+  rdma_get_ll_mac(&dst.sin6_addr, 
mac);<BR>+ else if (rdma_is_multicast_addr(&dst.sin6_addr)) 
{<BR>+  rdma_get_mcast_mac(&dst.sin6_addr, 
mac);<BR>+  *is_mcast = 1;<BR>+ } else {<BR>+  err = 
-EINVAL; 
//jyang:todo<BR>+  ASSERT(FALSE);<BR>+ }<BR>+ return 
err;<BR>+}<BR>+<BR>+static struct ib_ah *create_ib_ah(struct ib_pd *pd, struct 
ib_ah_attr *ah_attr,<BR>+      struct mlx4_ib_ah 
*ah)<BR>+{<BR>  struct mlx4_dev *dev = 
to_mdev(pd->device)->dev;<BR>- struct mlx4_ib_ah 
*ah;<BR> <BR>  if 
(mlx4_is_barred(pd->device->dma_device))<BR>   return 
ERR_PTR(-EFAULT);<BR> <BR>- ah = kmalloc(sizeof *ah, 
GFP_ATOMIC);<BR>- if (!ah)<BR>-  return 
ERR_PTR(-ENOMEM);<BR> <BR>- memset(&ah->av, 0, sizeof 
ah->av);<BR>-<BR>- ah->av.port_pd = cpu_to_be32(to_mpd(pd)->pdn | 
(ah_attr->port_num << 24));<BR>- ah->av.g_slid  = 
ah_attr->src_path_bits;<BR>- ah->av.dlid    = 
cpu_to_be16(ah_attr->dlid);<BR>- if (ah_attr->static_rate) 
{<BR>-  ah->av.stat_rate = ah_attr->static_rate + 
MLX4_STAT_RATE_OFFSET;<BR>-  while (ah->av.stat_rate > 
IB_RATE_2_5_GBPS + MLX4_STAT_RATE_OFFSET 
&&<BR>-         !(1 << 
ah->av.stat_rate & 
dev->caps.stat_rate_support))<BR>-   --ah->av.stat_rate;<BR>- }<BR>- ah->av.sl_tclass_flowlabel 
= cpu_to_be32(ah_attr->sl << 28);<BR>+ ah->av.ib.port_pd = 
cpu_to_be32(to_mpd(pd)->pdn | (ah_attr->port_num << 
24));<BR>+ ah->av.ib.g_slid  = 
ah_attr->src_path_bits;<BR>  if (ah_attr->ah_flags & 
IB_AH_GRH) {<BR>-  ah->av.g_slid   |= 
0x80;<BR>-  ah->av.gid_index = 
ah_attr->grh.sgid_index;<BR>-  ah->av.hop_limit = 
ah_attr->grh.hop_limit;<BR>-  ah->av.sl_tclass_flowlabel 
|=<BR>+  ah->av.ib.g_slid   |= 
0x80;<BR>+  ah->av.ib.gid_index = 
ah_attr->grh.sgid_index;<BR>+  ah->av.ib.hop_limit = 
ah_attr->grh.hop_limit;<BR>+  ah->av.ib.sl_tclass_flowlabel 
|=<BR>    cpu_to_be32((ah_attr->grh.traffic_class 
<< 20) |<BR>         
ah_attr->grh.flow_label);<BR>-  memcpy(ah->av.dgid, 
ah_attr->grh.dgid.raw, 16);<BR>+  memcpy(ah->av.ib.dgid, 
ah_attr->grh.dgid.raw, 
16);<BR>  }<BR> <BR>+ ah->av.ib.dlid    = 
cpu_to_be16(ah_attr->dlid);<BR>+ if (ah_attr->static_rate) 
{<BR>+  ah->av.ib.stat_rate = ah_attr->static_rate + 
MLX4_STAT_RATE_OFFSET;<BR>+  while (ah->av.ib.stat_rate > 
IB_RATE_2_5_GBPS + MLX4_STAT_RATE_OFFSET 
&&<BR>+         !(1 << 
ah->av.ib.stat_rate & 
dev->caps.stat_rate_support))<BR>+   --ah->av.ib.stat_rate;<BR>+ }<BR>+ ah->av.ib.sl_tclass_flowlabel 
= cpu_to_be32(ah_attr->sl << 28);<BR>+<BR>  return 
&ah->ibah;<BR> }<BR> <BR>+struct ib_ah *create_rdmaoe_ah(struct 
ib_pd *pd, struct ib_ah_attr *ah_attr,<BR>+       
struct mlx4_ib_ah *ah)<BR>+{<BR>+ struct mlx4_ib_dev *ibdev = 
to_mdev(pd->device);<BR>+ struct mlx4_dev *dev = 
ibdev->dev;<BR>+ u8 mac[6];<BR>+ int err;<BR>+ int 
is_mcast;<BR>+<BR>+ if 
(mlx4_is_barred(pd->device->dma_device))<BR>+  return 
ERR_PTR(-EFAULT);<BR>+<BR>+ err = mlx4_ib_resolve_grh(ibdev, ah_attr, mac, 
&is_mcast);<BR>+ if (err)<BR>+  return 
ERR_PTR(err);<BR>+<BR>+ memcpy(ah->av.eth.mac_0_1, mac, 
2);<BR>+ memcpy(ah->av.eth.mac_2_5, mac + 2, 
4);<BR>+ ah->av.ib.port_pd = cpu_to_be32(to_mpd(pd)->pdn | 
(ah_attr->port_num << 24));<BR>+ ah->av.ib.g_slid = 
0x80;<BR>+ if (ah_attr->static_rate) 
{<BR>+  ah->av.ib.stat_rate = ah_attr->static_rate + 
MLX4_STAT_RATE_OFFSET;<BR>+  while (ah->av.ib.stat_rate > 
IB_RATE_2_5_GBPS + MLX4_STAT_RATE_OFFSET 
&&<BR>+         !(1 << 
ah->av.ib.stat_rate & 
dev->caps.stat_rate_support))<BR>+   --ah->av.ib.stat_rate;<BR>+ }<BR>+<BR>+ /*<BR>+  
* HW requires multicast LID so we just choose one.<BR>+  */<BR>+ if 
(is_mcast)<BR>+  ah->av.ib.dlid = 
cpu_to_be16(0xc000);<BR>+<BR>+ memcpy(ah->av.ib.dgid, 
ah_attr->grh.dgid.raw, 16);<BR>+ ah->av.ib.sl_tclass_flowlabel = 
cpu_to_be32(ah_attr->sl << 28);<BR>+<BR>+ return 
&ah->ibah;<BR>+}<BR>+<BR>+<BR>+struct ib_ah *mlx4_ib_create_ah(struct 
ib_pd *pd, struct ib_ah_attr *ah_attr)<BR>+{<BR>+ struct mlx4_ib_ah 
*ah;<BR>+ enum rdma_transport_type transport;<BR>+<BR>+ struct ib_ah 
*ret;<BR>+<BR>+ ah = kzalloc(sizeof *ah, GFP_ATOMIC);<BR>+ if 
(!ah)<BR>+  return ERR_PTR(-ENOMEM);<BR>+<BR>+ transport = 
rdma_port_get_transport(pd->device, ah_attr->port_num);<BR>+ if 
(transport == RDMA_TRANSPORT_RDMAOE) {<BR>+  if 
(!(ah_attr->ah_flags & IB_AH_GRH)) {<BR>+   ret = 
ERR_PTR(-EINVAL);<BR>+   goto out;<BR>+  } else 
{<BR>+   /* TBD: need to handle the case when we get 
called<BR>+   in an atomic context and there we might sleep. 
We<BR>+   don't expect this currently since we're working 
with<BR>+   link local addresses which we can translate 
without<BR>+   going to sleep */<BR>+   ret = 
create_rdmaoe_ah(pd, ah_attr, ah);<BR>+   if 
(IS_ERR(ret))<BR>+    goto 
out;<BR>+   else<BR>+    return 
ret;<BR>+  }<BR>+ } else<BR>+  return create_ib_ah(pd, 
ah_attr, ah); /* never fails 
*/<BR>+<BR>+out:<BR>+ kfree(ah);<BR>+ return 
ret;<BR>+}<BR>+<BR>+<BR> int mlx4_ib_query_ah(struct ib_ah *ibah, struct 
ib_ah_attr *ah_attr)<BR> {<BR>  struct mlx4_ib_ah *ah = 
to_mah(ibah);<BR>+ enum rdma_transport_type 
transport;<BR> <BR>+ transport = 
rdma_port_get_transport(ibah->device, 
ah_attr->port_num);<BR>+<BR>  if 
(mlx4_is_barred(ibah->device->dma_device))<BR>   return 
-EFAULT;<BR> <BR>  memset(ah_attr, 0, sizeof 
*ah_attr);<BR>- ah_attr->dlid        

be16_to_cpu(ah->av.dlid);<BR>- ah_attr->sl        
= (u8)(be32_to_cpu(ah->av.sl_tclass_flowlabel) >> 
28);<BR>- ah_attr->port_num      = 
(u8)(be32_to_cpu(ah->av.port_pd) >> 24);<BR>- if 
(ah->av.stat_rate)<BR>-  ah_attr->static_rate = 
ah->av.stat_rate - MLX4_STAT_RATE_OFFSET;<BR>- ah_attr->src_path_bits 
= ah->av.g_slid & 
0x7F;<BR>+ ah_attr->dlid        = 
transport == RDMA_TRANSPORT_IB ? be16_to_cpu(ah->av.ib.dlid) : 
0;<BR>+ ah_attr->sl        = 
(u8)(be32_to_cpu(ah->av.ib.sl_tclass_flowlabel) >> 
28);<BR>+ ah_attr->port_num      = 
(u8)(be32_to_cpu(ah->av.ib.port_pd) >> 24);<BR>+ if 
(ah->av.ib.stat_rate)<BR>+  ah_attr->static_rate = 
ah->av.ib.stat_rate - 
MLX4_STAT_RATE_OFFSET;<BR>+ ah_attr->src_path_bits = ah->av.ib.g_slid 
& 0x7F;<BR> <BR>  if (mlx4_ib_ah_grh_present(ah)) 
{<BR>   ah_attr->ah_flags = 
IB_AH_GRH;<BR> <BR>   ah_attr->grh.traffic_class 
=<BR>-   (u8)(be32_to_cpu(ah->av.sl_tclass_flowlabel) >> 
20);<BR>+   (u8)(be32_to_cpu(ah->av.ib.sl_tclass_flowlabel) 
>> 20);<BR>   ah_attr->grh.flow_label 
=<BR>-   be32_to_cpu(ah->av.sl_tclass_flowlabel) & 
0xfffff;<BR>-  ah_attr->grh.hop_limit  = 
ah->av.hop_limit;<BR>-  ah_attr->grh.sgid_index = 
ah->av.gid_index;<BR>-  memcpy(ah_attr->grh.dgid.raw, 
ah->av.dgid, 
16);<BR>+   be32_to_cpu(ah->av.ib.sl_tclass_flowlabel) & 
0xfffff;<BR>+  ah_attr->grh.hop_limit  = 
ah->av.ib.hop_limit;<BR>+  ah_attr->grh.sgid_index = 
ah->av.ib.gid_index;<BR>+  memcpy(ah_attr->grh.dgid.raw, 
ah->av.ib.dgid, 16);<BR>  }<BR> <BR>  return 
0;<BR>@@ -108,7 +239,7 @@<BR> // Leo: temporary <BR> int 
mlx4_ib_modify_ah( struct ib_ah *ibah, struct ib_ah_attr *ah_attr 
)<BR> {<BR>- struct mlx4_av *av  = 
&to_mah(ibah)->av;<BR>+ struct mlx4_av *av  = 
&to_mah(ibah)->av.ib;<BR>  struct mlx4_dev *dev = 
to_mdev(ibah->pd->device)->dev;<BR> <BR>  if 
(mlx4_is_barred(dev))<BR>Index: 
hw/mlx4/kernel/bus/ib/main.c<BR>===================================================================<BR>--- 
hw/mlx4/kernel/bus/ib/main.c (revision 2617)<BR>+++ 
hw/mlx4/kernel/bus/ib/main.c (working copy)<BR>@@ -133,31 +133,21 
@@<BR>  return err;<BR> }<BR> <BR>-static int 
mlx4_ib_query_port(struct ib_device *ibdev, u8 
port,<BR>-         struct ib_port_attr 
*props)<BR>+<BR>+static enum 
rdma_transport_type<BR>+mlx4_ib_port_get_transport(struct ib_device *device, u8 
port_num)<BR> {<BR>- struct ib_smp *in_mad  = 
NULL;<BR>- struct ib_smp *out_mad = NULL;<BR>- int err = 
-ENOMEM;<BR>+ struct mlx4_dev *dev = 
to_mdev(device)->dev;<BR> <BR>- if 
(mlx4_is_barred(ibdev->dma_device))<BR>-  return 
-EFAULT;<BR>- <BR>- in_mad  = kzalloc(sizeof *in_mad, 
GFP_KERNEL);<BR>- out_mad = kmalloc(sizeof *out_mad, 
GFP_KERNEL);<BR>- if (!in_mad || !out_mad)<BR>-  goto 
out;<BR>+ return dev->caps.port_mask & (1 << (port_num - 1)) 
?<BR>+  RDMA_TRANSPORT_IB : 
RDMA_TRANSPORT_RDMAOE;<BR>+}<BR> <BR>- memset(props, 0, sizeof 
*props);<BR> <BR>- init_query_mad(in_mad);<BR>- in_mad->attr_id  
= IB_SMP_ATTR_PORT_INFO;<BR>- in_mad->attr_mod = 
cpu_to_be32(port);<BR>-<BR>- err = mlx4_MAD_IFC(to_mdev(ibdev), 1, 1, port, 
NULL, NULL, in_mad, out_mad);<BR>- if (err)<BR>-  goto 
out;<BR>-<BR>+static void ib_link_query_port(struct ib_device *ibdev, u8 
port,<BR>+          struct 
ib_port_attr *props,<BR>+          
struct ib_smp *out_mad)<BR>+{<BR>  props->lid  = 
be16_to_cpup((__be16 *) (out_mad->data + 
16));<BR>  props->lmc  = out_mad->data[34] & 
0x7;<BR>  props->sm_lid  = be16_to_cpup((__be16 *) 
(out_mad->data + 18));<BR>@@ -177,7 +167,64 
@@<BR>  props->subnet_timeout = out_mad->data[51] & 
0x1f;<BR>  props->max_vl_num = out_mad->data[37] >> 
4;<BR>  props->init_type_reply = out_mad->data[41] >> 
4;<BR>+ props->transport= RDMA_TRANSPORT_IB;<BR>+}<BR> <BR>+static 
void eth_link_query_port(struct ib_device *ibdev, u8 
port,<BR>+    struct ib_port_attr 
*props,<BR>+    struct ib_smp 
*out_mad)<BR>+{<BR>+<BR>+ props->port_cap_flags = 
be32_to_cpup((__be32 *) (out_mad->data + 
20));<BR>+ props->gid_tbl_len = 
to_mdev(ibdev)->dev->caps.gid_table_len[port];<BR>+ props->max_msg_sz = 
to_mdev(ibdev)->dev->caps.max_msg_sz;<BR>+ props->pkey_tbl_len = 
(u16)to_mdev(ibdev)->dev->caps.pkey_table_len[port];<BR>+ props->bad_pkey_cntr = 
be16_to_cpup((__be16 *) (out_mad->data + 
46));<BR>+ props->qkey_viol_cntr = be16_to_cpup((__be16 *) 
(out_mad->data + 48));<BR>+ props->active_width = 
out_mad->data[31] & 0xf;<BR>+ props->active_speed = 
out_mad->data[35] >> 4;<BR>+ props->max_mtu  = 
out_mad->data[41] & 0xf;<BR>+ //props->active_mtu = 
rdmaoe->mtu[port - 1];<BR>+ props->active_mtu = 1500; 
//jyang:hardcoded<BR>+ props->subnet_timeout = out_mad->data[51] 
& 0x1f;<BR>+ props->max_vl_num = out_mad->data[37] >> 
4;<BR>+ props->init_type_reply = out_mad->data[41] >> 
4;<BR>+ props->transport= 
RDMA_TRANSPORT_RDMAOE;<BR>+<BR>+ //props->state  = 
netif_running(ndev) &&  netif_oper_up(ndev) 
?<BR>+ //    IB_PORT_ACTIVE : 
IB_PORT_DOWN;<BR>+ props->state  = IB_PORT_ACTIVE; //jyang: 
just hardcoded it now<BR>+ props->phys_state = 
props->state;<BR>+}<BR>+<BR>+<BR>+<BR>+static int mlx4_ib_query_port(struct 
ib_device *ibdev, u8 port,<BR>+    
         struct ib_port_attr 
*props)<BR>+{<BR>+ struct ib_smp *in_mad  = NULL;<BR>+ struct 
ib_smp *out_mad = NULL;<BR>+ int err = -ENOMEM;<BR>+<BR>+ in_mad  
= kzalloc(sizeof *in_mad, GFP_KERNEL);<BR>+ out_mad = kmalloc(sizeof 
*out_mad, GFP_KERNEL);<BR>+ if (!in_mad || !out_mad)<BR>+  goto 
out;<BR>+<BR>+ memset(props, 0, sizeof 
*props);<BR>+<BR>+ init_query_mad(in_mad);<BR>+ in_mad->attr_id  
= IB_SMP_ATTR_PORT_INFO;<BR>+ in_mad->attr_mod = 
cpu_to_be32(port);<BR>+<BR>+ err = mlx4_MAD_IFC(to_mdev(ibdev), 1, 1, port, 
NULL, NULL, in_mad, out_mad);<BR>+ if (err)<BR>+  goto 
out;<BR>+<BR>+ mlx4_ib_port_get_transport(ibdev, port) == RDMA_TRANSPORT_IB 
?<BR>+  ib_link_query_port(ibdev, port, props, out_mad) 
:<BR>+  eth_link_query_port(ibdev, port, props, 
out_mad);<BR>+<BR> out:<BR>  kfree(in_mad);<BR>  kfree(out_mad);<BR>@@ 
-522,6 +569,7 @@<BR>  ibdev->ib_dev.uverbs_abi_ver = 
MLX4_IB_UVERBS_ABI_VERSION;<BR>  ibdev->ib_dev.query_device = 
mlx4_ib_query_device;<BR>  ibdev->ib_dev.query_port = 
mlx4_ib_query_port;<BR>+ ibdev->ib_dev.get_port_transport = 
mlx4_ib_port_get_transport;<BR>  ibdev->ib_dev.query_gid_chunk = 
mlx4_ib_query_gid_chunk;<BR>  ibdev->ib_dev.query_pkey_chunk = 
mlx4_ib_query_pkey_chunk;<BR>  ibdev->ib_dev.modify_device = 
mlx4_ib_modify_device;<BR>Index: 
hw/mlx4/kernel/bus/ib/mlx4_ib.h<BR>===================================================================<BR>--- 
hw/mlx4/kernel/bus/ib/mlx4_ib.h (revision 2617)<BR>+++ 
hw/mlx4/kernel/bus/ib/mlx4_ib.h (working copy)<BR>@@ -165,14 +165,15 
@@<BR> <BR> struct mlx4_ib_ah {<BR>  struct 
ib_ah  ibah;<BR>- struct mlx4_av  av;<BR>+ union 
mlx4_ext_av   av;<BR> };<BR> <BR>+<BR> enum 
{<BR>  /*<BR>   * Largest possible UD header: send with GRH 
and immediate data.<BR>   
*/<BR>- MLX4_IB_UD_HEADER_SIZE  = 
72<BR>+ MLX4_IB_UD_HEADER_SIZE  = 
76<BR> };<BR> <BR> struct mlx4_ib_sqp {<BR>@@ -180,7 +181,10 
@@<BR>  int   pkey_index;<BR>  u32   qkey;<BR>  u32   send_psn;<BR>- struct 
ib_ud_header ud_header;<BR>+ union {<BR>+  struct 
ib_ud_header ib;<BR>+  struct eth_ud_header eth;<BR>+ } 
hdr;<BR>  u8   header_buf[MLX4_IB_UD_HEADER_SIZE];<BR> };<BR> <BR>@@ 
-340,9 +344,14 @@<BR> int __init mlx4_ib_init(void);<BR> void __exit 
mlx4_ib_cleanup(void);<BR> <BR>+int mlx4_ib_resolve_grh(struct mlx4_ib_dev 
*dev, const struct ib_ah_attr *ah_attr,<BR>+   u8 *mac, int 
*is_mcast);<BR>+<BR>+<BR> static inline int mlx4_ib_ah_grh_present(struct 
mlx4_ib_ah *ah)<BR> {<BR>- return !!(ah->av.g_slid & 
0x80);<BR>+ return !!(ah->av.ib.g_slid & 
0x80);<BR>+<BR> }<BR> <BR> #endif /* MLX4_IB_H */<BR>Index: 
hw/mlx4/kernel/bus/ib/qp.c<BR>===================================================================<BR>--- 
hw/mlx4/kernel/bus/ib/qp.c (revision 2617)<BR>+++ 
hw/mlx4/kernel/bus/ib/qp.c (working copy)<BR>@@ -46,10 +46,16 
@@<BR> <BR> enum {<BR>  MLX4_IB_DEFAULT_SCHED_QUEUE = 
0x83,<BR>- MLX4_IB_DEFAULT_QP0_SCHED_QUEUE = 
0x3f<BR>+ MLX4_IB_DEFAULT_QP0_SCHED_QUEUE = 
0x3f,<BR>+ MLX4_IB_LINK_TYPE_IB  = 
0,<BR>+ MLX4_IB_LINK_TYPE_ETH  = 
1<BR> };<BR> <BR> enum {<BR>+ MLX4_RDMAOE_ETHERTYPE = 
0x8915<BR>+};<BR>+<BR>+enum {<BR>  MLX4_IB_MIN_SQ_STRIDE = 
6<BR> };<BR> <BR>@@ -65,6 +71,8 
@@<BR>  __constant_cpu_to_be32(MLX4_OPCODE_NOP)    /* [IB_WR_NOP]     */<BR> };<BR> <BR>+extern 
inline void rdma_get_ll_mac(struct in6_addr *addr, u8 
*mac);<BR>+<BR> static struct mlx4_ib_sqp *to_msqp(struct mlx4_ib_qp 
*mqp)<BR> {<BR>  return container_of(mqp, struct mlx4_ib_sqp, 
qp);<BR>@@ -724,6 +732,12 @@<BR> static int mlx4_set_path(struct 
mlx4_ib_dev *dev, const struct ib_ah_attr *ah,<BR>     
struct mlx4_qp_path *path, u8 port)<BR> {<BR>+ int err;<BR>+ int 
is_eth = rdma_port_get_transport(&dev->ib_dev, port) 
==<BR>+  RDMA_TRANSPORT_RDMAOE ? 1 : 0;<BR>+ u8 
mac[6];<BR>+ int 
is_mcast;<BR>+<BR>  path->grh_mylmc     = 
ah->src_path_bits & 
0x7f;<BR>  path->rlid     = 
cpu_to_be16(ah->dlid);<BR>  if (ah->static_rate) {<BR>@@ -754,7 
+768,21 @@<BR>  path->sched_queue = MLX4_IB_DEFAULT_SCHED_QUEUE 
|<BR>   ((port - 1) << 6) | ((ah->sl & 0xf) << 
2);<BR> <BR>- return 0;<BR>+ if (is_eth) {<BR>+  if 
(!(ah->ah_flags & IB_AH_GRH))<BR>+   return 
-1;<BR>+<BR>+  err = mlx4_ib_resolve_grh(dev, ah, mac, 
&is_mcast);<BR>+  if (err)<BR>+   return 
err;<BR>+<BR>+  memcpy(path->dmac, mac, 
6);<BR>+  path->ackto = MLX4_IB_LINK_TYPE_ETH;<BR>+  /* 
use index 0 into MAC table for RDMAoE */<BR>+  path->grh_mylmc 
&= 0x80;<BR>+ }<BR>+<BR>+    return 
0;<BR> }<BR> <BR> static int __mlx4_ib_modify_qp(struct ib_qp 
*ibqp,<BR>@@ -1146,79 +1174,132 @@<BR>  return 
opcode;<BR> }<BR> <BR>+<BR>+<BR>+<BR> static int 
build_mlx_header(struct mlx4_ib_sqp *sqp, ib_send_wr_t 
*wr,<BR>-       void 
*wqe)<BR>+       void *wqe, unsigned 
*mlx_seg_len)<BR> {<BR>  enum ib_wr_opcode opcode = 
to_wr_opcode(wr);<BR>  struct ib_device *ib_dev = 
&to_mdev(sqp->qp.ibqp.device)->ib_dev;<BR>  struct 
mlx4_wqe_mlx_seg *mlx = wqe;<BR>  struct mlx4_wqe_inline_seg *inl = 
(void*)((u8*)wqe + sizeof *mlx);<BR>  struct mlx4_ib_ah *ah = 
to_mah((struct ib_ah *)wr->dgrm.ud.h_av);<BR>- __be16 
pkey;<BR>+ u16 pkey;<BR>  int send_size;<BR>  int 
header_size;<BR>  int spc;<BR>- u32 i;<BR>+ u16 
i;<BR>+ struct ib_ud_header *ib = NULL;<BR>+ struct eth_ud_header *eth 
= NULL;<BR>+ struct ib_unpacked_grh *grh;<BR>+ struct 
ib_unpacked_bth  *bth;<BR>+ struct ib_unpacked_deth 
*deth;<BR>+ u8 *tmp;<BR>+ u8 
mac[6];<BR> <BR>  send_size = 0;<BR>  for (i = 0; i 
< wr->num_ds; ++i)<BR>   send_size += 
wr->ds_array[i].length;<BR> <BR>- ib_ud_header_init(send_size, 
mlx4_ib_ah_grh_present(ah), &sqp->ud_header);<BR>+ if 
(rdma_port_get_transport(sqp->qp.ibqp.device, sqp->qp.port) == 
RDMA_TRANSPORT_IB) 
{<BR> <BR>- sqp->ud_header.lrh.service_level   
=<BR>-  (u8)(be32_to_cpu(ah->av.sl_tclass_flowlabel) >> 
28);<BR>- sqp->ud_header.lrh.destination_lid = 
ah->av.dlid;<BR>- sqp->ud_header.lrh.source_lid      
= cpu_to_be16(ah->av.g_slid & 0x7f);<BR>+  ib = 
&sqp->hdr.ib;<BR>+  grh = &ib->grh;<BR>+  bth 
= &ib->bth;<BR>+  deth = 
&ib->deth;<BR>+  ib_ud_header_init(send_size, 
mlx4_ib_ah_grh_present(ah), 
ib);<BR>+  ib->lrh.service_level   
=<BR>+   (u8)(be32_to_cpu(ah->av.ib.sl_tclass_flowlabel) 
>> 28);<BR>+  ib->lrh.destination_lid = 
ah->av.ib.dlid;<BR>+  ib->lrh.source_lid      
= cpu_to_be16(ah->av.ib.g_slid & 0x7f);<BR>+ } else 
{<BR>+  eth = &sqp->hdr.eth;<BR>+  grh = 
&eth->grh;<BR>+  bth = &eth->bth;<BR>+  deth = 
&eth->deth;<BR>+  ib_rdmaoe_ud_header_init(send_size, 
mlx4_ib_ah_grh_present(ah), eth);<BR>+ }<BR>+<BR>+ <BR>  if 
(mlx4_ib_ah_grh_present(ah)) 
{<BR>-  sqp->ud_header.grh.traffic_class 
=<BR>-   (u8)((be32_to_cpu(ah->av.sl_tclass_flowlabel) 
>> 20) & 
0xff);<BR>-  sqp->ud_header.grh.flow_label    
=<BR>-   ah->av.sl_tclass_flowlabel & 
cpu_to_be32(0xfffff);<BR>-  sqp->ud_header.grh.hop_limit     
= ah->av.hop_limit;<BR>-  ib_get_cached_gid(ib_dev, 
(u8)(be32_to_cpu(ah->av.port_pd) >> 
24),<BR>-      ah->av.gid_index, 
&sqp->ud_header.grh.source_gid);<BR>-  memcpy(sqp->ud_header.grh.destination_gid.raw,<BR>-         
ah->av.dgid, 16);<BR>+  grh->traffic_class 
=<BR>+   (u8)((be32_to_cpu(ah->av.ib.sl_tclass_flowlabel) 
>> 20) & 0xff);<BR>+  grh->flow_label    
=<BR>+   ah->av.ib.sl_tclass_flowlabel & 
cpu_to_be32(0xfffff);<BR>+  grh->hop_limit     
= ah->av.ib.hop_limit;<BR>+  ib_get_cached_gid(ib_dev, 
(u8)(be32_to_cpu(ah->av.ib.port_pd) >> 
24),<BR>+      ah->av.ib.gid_index, 
&grh->source_gid);<BR>+  memcpy(grh->destination_gid.raw,<BR>+      
ah->av.ib.dgid, 16);<BR>  }<BR> <BR>  mlx->flags 
&= cpu_to_be32(MLX4_WQE_CTRL_CQ_UPDATE);<BR>- mlx->flags |= 
cpu_to_be32((!sqp->qp.ibqp.qp_num ? MLX4_WQE_MLX_VL15 : 0) 
|<BR>-      (sqp->ud_header.lrh.destination_lid 
==<BR>-       XIB_LID_PERMISSIVE ? 
MLX4_WQE_MLX_SLR : 0) |<BR>-      
(sqp->ud_header.lrh.service_level << 
8));<BR>- mlx->rlid   = 
sqp->ud_header.lrh.destination_lid;<BR> <BR>+ if (ib) 
{<BR>+  mlx->flags |= cpu_to_be32((!sqp->qp.ibqp.qp_num ? 
MLX4_WQE_MLX_VL15 : 0) |<BR>+       
(ib->lrh.destination_lid ==<BR>+        
IB_LID_PERMISSIVE ? MLX4_WQE_MLX_SLR : 0) 
|<BR>+       (ib->lrh.service_level << 
8));<BR>+  mlx->rlid   = 
ib->lrh.destination_lid;<BR>+<BR>+ }<BR>+<BR>  switch (opcode) 
{<BR>  case 
IB_WR_SEND:<BR>-  sqp->ud_header.bth.opcode  = 
IB_OPCODE_UD_SEND_ONLY;<BR>-  sqp->ud_header.immediate_present = 
0;<BR>+  bth->opcode  = 
IB_OPCODE_UD_SEND_ONLY;<BR>+  if 
(ib)<BR>+   ib->immediate_present = 
0;<BR>+  else<BR>+   eth->immediate_present = 
0;<BR>   break;<BR>  case 
IB_WR_SEND_WITH_IMM:<BR>-  sqp->ud_header.bth.opcode  = 
IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE;<BR>-  sqp->ud_header.immediate_present 
= 1;<BR>-  sqp->ud_header.immediate_data    = 
wr->immediate_data;<BR>+  bth->opcode  = 
IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE;<BR>+  if (ib) 
{<BR>+   ib->immediate_present = 
1;<BR>+   ib->immediate_data    = 
wr->immediate_data;<BR>+  } else 
{<BR>+   eth->immediate_present = 
1;<BR>+   eth->immediate_data    = 
wr->immediate_data;<BR>+  }<BR>   break;<BR>  default:<BR>   return 
-EINVAL;<BR>  }<BR> <BR>- sqp->ud_header.lrh.virtual_lane    
= !sqp->qp.ibqp.qp_num ? 15 : 0;<BR>- if 
(sqp->ud_header.lrh.destination_lid == 
IB_LID_PERMISSIVE)<BR>-  sqp->ud_header.lrh.source_lid = 
IB_LID_PERMISSIVE;<BR>- sqp->ud_header.bth.solicited_event = 
(u8)(!!(wr->send_opt & IB_SEND_OPT_SOLICITED));<BR>+ if (ib) 
{<BR>+  ib->lrh.virtual_lane    = 
!sqp->qp.ibqp.qp_num ? 15 : 0;<BR>+  if (ib->lrh.destination_lid 
== IB_LID_PERMISSIVE)<BR>+   ib->lrh.source_lid = 
IB_LID_PERMISSIVE;<BR>+ } else {<BR>+  memcpy(eth->eth.dmac_h, 
ah->av.eth.mac_0_1, 2);<BR>+  memcpy(eth->eth.dmac_h + 2, 
ah->av.eth.mac_2_5, 2);<BR>+  memcpy(eth->eth.dmac_l, 
ah->av.eth.mac_2_5 + 2, 2);<BR>+  rdma_get_ll_mac((struct in6_addr 
*)&grh->source_gid, mac);<BR>+<BR>+  tmp = 
mac;<BR>+  memcpy(eth->eth.smac_h, tmp, 
2);<BR>+  memcpy(eth->eth.smac_l, tmp + 2, 
4);<BR>+  eth->eth.type = 
cpu_to_be16(MLX4_RDMAOE_ETHERTYPE);<BR>+ }<BR>+<BR>+ bth->solicited_event 
= (u8)(!!(wr->send_opt & IB_SEND_SOLICITED));<BR>+<BR>  if 
(!sqp->qp.ibqp.qp_num)<BR>   ib_get_cached_pkey(ib_dev, 
sqp->qp.port, sqp->pkey_index, 
&pkey);<BR>  else<BR>   ib_get_cached_pkey(ib_dev, 
sqp->qp.port, wr->dgrm.ud.pkey_index, 
&pkey);<BR>- sqp->ud_header.bth.pkey = 
pkey;<BR>- sqp->ud_header.bth.destination_qpn = 
wr->dgrm.ud.remote_qp;<BR>- sqp->ud_header.bth.psn = 
cpu_to_be32((sqp->send_psn++) & ((1 << 24) - 
1));<BR>- sqp->ud_header.deth.qkey = wr->dgrm.ud.remote_qkey & 
0x00000080 ?<BR>-  cpu_to_be32(sqp->qkey) : 
wr->dgrm.ud.remote_qkey;<BR>- sqp->ud_header.deth.source_qpn = 
cpu_to_be32(sqp->qp.ibqp.qp_num);<BR>+ bth->pkey = 
pkey;<BR>+ bth->destination_qpn = 
wr->dgrm.ud.remote_qp;<BR>+ bth->psn = 
cpu_to_be32((sqp->send_psn++) & ((1 << 24) - 
1));<BR>+ deth->qkey = wr->dgrm.ud.remote_qkey & 0x80000000 
?<BR>+         cpu_to_be32(sqp->qkey) 
: wr->dgrm.ud.remote_qkey;<BR>+ deth->source_qpn = 
cpu_to_be32(sqp->qp.ibqp.qp_num);<BR> <BR>- header_size = 
ib_ud_header_pack(&sqp->ud_header, sqp->header_buf);<BR>+ if 
(ib)<BR>+  header_size = ib_ud_header_pack(ib, 
sqp->header_buf);<BR>+ else<BR>+  header_size = 
rdmaoe_ud_header_pack(eth, sqp->header_buf);<BR> <BR> #if 
0<BR>  {<BR>@@ -1271,7 +1352,10 @@<BR>   i = 
2;<BR>  }<BR> <BR>- return ALIGN(i * sizeof (struct 
mlx4_wqe_inline_seg) + header_size, 16);<BR>+ *mlx_seg_len 
=<BR>+  ALIGN(i * sizeof (struct mlx4_wqe_inline_seg) + header_size, 
16);<BR>+ return 0;<BR>+<BR> }<BR> <BR> static int 
mlx4_wq_overflow(struct mlx4_ib_wq *wq, int nreq, struct ib_cq *ib_cq)<BR>@@ 
-1314,9 +1398,13 @@<BR> static void set_datagram_seg(struct 
mlx4_wqe_datagram_seg *dseg,<BR>         
ib_send_wr_t *wr)<BR> {<BR>+<BR>  memcpy(dseg->av, 
&to_mah((struct ib_ah *)wr->dgrm.ud.h_av)->av, sizeof (struct 
mlx4_av));<BR>  dseg->dqpn = 
wr->dgrm.ud.remote_qp;<BR>  dseg->qkey = 
wr->dgrm.ud.remote_qkey;<BR>+ dseg->vlan = to_mah((struct ib_ah 
*)wr->dgrm.ud.h_av)->av.eth.vlan;<BR>+ memcpy(dseg->mac_0_1, 
to_mah((struct ib_ah *)wr->dgrm.ud.h_av)->av.eth.mac_0_1, 
6);<BR>+<BR> }<BR> <BR> static void set_mlx_icrc_seg(void 
*dseg)<BR>@@ -1398,7 +1486,7 @@<BR> int mlx4_ib_post_send(struct ib_qp 
*ibqp, ib_send_wr_t *wr,<BR>         
ib_send_wr_t **bad_wr)<BR> {<BR>- enum ib_wr_opcode 
opcode;<BR>+ enum ib_wr_opcode opcode;// = 
to_wr_opcode(wr);<BR>  struct mlx4_ib_qp *qp = 
to_mqp(ibqp);<BR>  struct mlx4_dev *dev = 
to_mdev(ibqp->device)->dev;<BR>  u8 *wqe /*, *wqe_start*/;<BR>@@ 
-1525,16 +1613,14 @@<BR> <BR>   case 
IB_QPT_SMI:<BR>   case IB_QPT_GSI:<BR>-   err = 
build_mlx_header(to_msqp(qp), wr, ctrl);<BR>+   err = 
build_mlx_header(to_msqp(qp), wr, ctrl, 
&seglen);<BR>    if (err < 0) 
{<BR>     if 
(bad_wr)<BR>      *bad_wr = 
wr;<BR>     goto 
out;<BR>    }<BR>-   <BR>-   wqe  
+= err;<BR>-   size += err / 
16;<BR>-<BR>+   wqe  += seglen;<BR>+   size 
+= seglen / 16;<BR>    err = 
0;<BR>    break;<BR> <BR>Index: 
hw/mlx4/kernel/bus/inc/cmd.h<BR>===================================================================<BR>--- 
hw/mlx4/kernel/bus/inc/cmd.h (revision 2617)<BR>+++ 
hw/mlx4/kernel/bus/inc/cmd.h (working copy)<BR>@@ -138,6 +138,7 
@@<BR>  MLX4_SET_PORT_MAC_TABLE = 
0x2,<BR>  MLX4_SET_PORT_VLAN_TABLE = 
0x3,<BR>  MLX4_SET_PORT_PRIO_MAP  = 
0x4,<BR>+ MLX4_SET_PORT_GID_TABLE = 
0x5,<BR> };<BR> <BR> struct mlx4_dev;<BR>Index: 
hw/mlx4/kernel/bus/inc/device.h<BR>===================================================================<BR>--- 
hw/mlx4/kernel/bus/inc/device.h (revision 2617)<BR>+++ 
hw/mlx4/kernel/bus/inc/device.h (working copy)<BR>@@ -208,8 +208,9 
@@<BR>  int   log_num_prios;<BR>  int   num_fc_exch;<BR>  enum 
mlx4_port_type port_type[MLX4_MAX_PORTS + 1];<BR>-    enum 
mlx4_port_state port_state[MLX4_MAX_PORTS + 1];<BR>-    
int   reserved_fexch_mpts_base;   
<BR>+ u32   port_mask;<BR>+ enum mlx4_port_state 
port_state[MLX4_MAX_PORTS + 
1];<BR>+ int   reserved_fexch_mpts_base;   
<BR>  int   total_reserved_qps;<BR> };<BR> <BR>@@ 
-343,6 +344,28 
@@<BR>  u8   dgid[16];<BR> };<BR> <BR>+struct 
mlx4_eth_av 
{<BR>+ __be32  port_pd;<BR>+ u8  reserved1;<BR>+ u8  smac_idx;<BR>+ u16  reserved2;<BR>+ u8  reserved3;<BR>+ u8  gid_index;<BR>+ u8  stat_rate;<BR>+ u8  hop_limit;<BR>+ __be32  sl_tclass_flowlabel;<BR>+ u8  dgid[16];<BR>+ u32  reserved4[2];<BR>+ __be16  vlan;<BR>+ u8  mac_0_1[2];<BR>+ u8  mac_2_5[4];<BR>+};<BR>+<BR>+union 
mlx4_ext_av {<BR>+ struct mlx4_av  ib;<BR>+ struct 
mlx4_eth_av eth;<BR>+};<BR>+<BR> #define 
MLX4_DEV_SIGNATURE 0xf1b34a6e<BR> <BR> struct mlx4_dev_params 
{<BR>Index: 
hw/mlx4/kernel/bus/inc/ib_pack.h<BR>===================================================================<BR>--- 
hw/mlx4/kernel/bus/inc/ib_pack.h (revision 2617)<BR>+++ 
hw/mlx4/kernel/bus/inc/ib_pack.h (working copy)<BR>@@ -39,6 +39,7 
@@<BR> <BR> enum {<BR>  IB_LRH_BYTES  = 
8,<BR>+ IB_ETH_BYTES  = 14,<BR>  IB_GRH_BYTES  = 
40,<BR>  IB_BTH_BYTES  = 12,<BR>  IB_DETH_BYTES = 
8<BR>@@ -212,6 +213,15 
@@<BR>  __be32       
source_qpn;<BR> };<BR> <BR>+struct ib_unpacked_eth 
{<BR>+ u8 dmac_h[4];<BR>+ u8 dmac_l[2];<BR>+ u8 smac_h[2];<BR>+ u8 smac_l[4];<BR>+ __be16 type;<BR>+};<BR>+<BR>+<BR> struct 
ib_ud_header {<BR>  struct ib_unpacked_lrh  
lrh;<BR>  int                     
grh_present;<BR>@@ -222,6 +232,19 
@@<BR>  __be32         
  immediate_data;<BR> };<BR> <BR>+<BR>+<BR>+struct 
eth_ud_header {<BR>+ struct ib_unpacked_eth  
eth;<BR>+ int                     
grh_present;<BR>+ struct ib_unpacked_grh  grh;<BR>+ struct 
ib_unpacked_bth  bth;<BR>+ struct ib_unpacked_deth 
deth;<BR>+ int            
  immediate_present;<BR>+ __be32         
  immediate_data;<BR>+};<BR>+<BR>+<BR> void ib_pack(const struct 
ib_field        
*desc,<BR>       
int                           
desc_len,<BR>       
void                         
*structure,<BR>@@ -236,10 +259,18 
@@<BR>          
int         
grh_present,<BR>          struct 
ib_ud_header *header);<BR> <BR>+void 
ib_rdmaoe_ud_header_init(int          
payload_bytes,<BR>+      int    
     grh_present,<BR>+      struct 
eth_ud_header   *header);<BR>+<BR> int ib_ud_header_pack(struct 
ib_ud_header *header,<BR>         
void                
*buf);<BR> <BR> int 
ib_ud_header_unpack(void                
*buf,<BR>    struct ib_ud_header *header);<BR> <BR>+int 
rdmaoe_ud_header_pack(struct eth_ud_header 
*header,<BR>+         
void                 
*buf);<BR>+<BR>+<BR> #endif /* IB_PACK_H */<BR>Index: 
hw/mlx4/kernel/bus/inc/ib_verbs.h<BR>===================================================================<BR>--- 
hw/mlx4/kernel/bus/inc/ib_verbs.h (revision 2617)<BR>+++ 
hw/mlx4/kernel/bus/inc/ib_verbs.h (working copy)<BR>@@ -53,6 +53,34 
@@<BR> <BR> #include "ib_verbs_ex.h"<BR> <BR>+/*<BR>+ * IPv6 
address structure<BR>+ */<BR>+<BR>+struct in6_addr<BR>+{<BR>+ union 
<BR>+ {<BR>+  __u8  u6_addr8[16];<BR>+  __be16  u6_addr16[8];<BR>+  __be32  u6_addr32[4];<BR>+ } 
in6_u;<BR>+#define s6_addr   in6_u.u6_addr8<BR>+#define 
s6_addr16  in6_u.u6_addr16<BR>+#define 
s6_addr32  in6_u.u6_addr32<BR>+};<BR>+<BR>+<BR>+struct sockaddr_in6 
{<BR>+ unsigned short int sin6_family;    /* AF_INET6 
*/<BR>+ __be16   sin6_port;      /* 
Transport layer port # */<BR>+ __be32   sin6_flowinfo;  
/* IPv6 flow information */<BR>+ struct 
in6_addr  sin6_addr;      /* IPv6 address 
*/<BR>+ __u32   sin6_scope_id;  /* scope id (new in 
RFC2553) */<BR>+};<BR>+<BR>+#define AF_INET6 10 /* IP version 
6   */<BR>+<BR> enum rdma_node_type {<BR>  /* IB 
values map to NodeInfo:NodeType. */<BR>  RDMA_NODE_IB_CA  = 
1,<BR>@@ -63,7 +91,8 @@<BR> <BR> enum rdma_transport_type 
{<BR>  RDMA_TRANSPORT_IB,<BR>- RDMA_TRANSPORT_IWARP<BR>+ RDMA_TRANSPORT_IWARP,<BR>+ RDMA_TRANSPORT_RDMAOE<BR> };<BR> <BR> enum 
rdma_transport_type<BR>@@ -231,6 +260,7 
@@<BR>  u8   active_width;<BR>  u8   active_speed;<BR>  u8                      
phys_state;<BR>+ enum 
rdma_transport_type transport;<BR> };<BR> <BR> enum 
ib_device_modify_flags {<BR>@@ -633,6 +663,10 
@@<BR>  IB_WR_ATOMIC_CMP_AND_SWP,<BR>  IB_WR_ATOMIC_FETCH_AND_ADD,<BR>  IB_WR_LSO,<BR>+ IB_WR_SEND_WITH_INV,<BR>+ IB_WR_RDMA_READ_WITH_INV,<BR>+ IB_WR_LOCAL_INV,<BR>+ IB_WR_FAST_REG_MR,<BR>  IB_WR_NOP<BR> };<BR> <BR>@@ 
-920,6 +954,9 
@@<BR>  int             
(*query_port)(struct ib_device 
*device,<BR>        u8 
port_num,<BR>        struct ib_port_attr 
*port_attr);<BR>+ enum rdma_transport_type   
(*get_port_transport)(struct ib_device 
*device,<BR>+        u8 
port_num);<BR>+<BR>  int             
(*query_gid_chunk)(struct ib_device 
*device,<BR>       u8 port_num, int 
index,<BR>       union ib_gid gid[8], int 
size);<BR>@@ -1127,6 +1164,11 @@<BR> int ib_query_port(struct ib_device 
*device,<BR>     u8 port_num, struct ib_port_attr 
*port_attr);<BR> <BR>+enum rdma_transport_type 
rdma_port_get_transport(struct ib_device 
*device,<BR>+       u8 port_num);<BR>+int 
rdma_is_transport_supported(struct ib_device 
*device,<BR>+    enum rdma_transport_type 
transport);<BR>+<BR> int ib_query_gid_chunk(struct ib_device 
*device,<BR>    u8 port_num, int index, union ib_gid gid[8], int 
size);<BR> <BR>Index: 
hw/mlx4/kernel/bus/inc/qp.h<BR>===================================================================<BR>--- 
hw/mlx4/kernel/bus/inc/qp.h (revision 2617)<BR>+++ 
hw/mlx4/kernel/bus/inc/qp.h (working copy)<BR>@@ -113,7 +113,9 
@@<BR>  u8   snooper_flags;<BR>  u8   reserved3[2];<BR>  u8   counter_index;<BR>- u8   reserved4[7];<BR>+ u8   reserved4;<BR>+ u8   dmac[6];<BR>+<BR> };<BR> <BR> struct 
mlx4_qp_context {<BR>@@ -213,7 +215,9 
@@<BR>  __be32   av[8];<BR>  __be32   dqpn;<BR>  __be32   qkey;<BR>- __be32   reservd[2];<BR>+ __be16   vlan;<BR>+ u8   mac_0_1[2];<BR>+ u8   mac_2_5[4];<BR> };<BR> <BR> #pragma 
warning( disable : 4200)<BR>Index: 
hw/mlx4/kernel/bus/net/main.c<BR>===================================================================<BR>--- 
hw/mlx4/kernel/bus/net/main.c (revision 2617)<BR>+++ 
hw/mlx4/kernel/bus/net/main.c (working copy)<BR>@@ -139,7 +139,9 
@@<BR>  int count = 0;<BR> <BR>  for (i = 0; i < 
dev->caps.num_ports; i++) {<BR>-  if (dev->caps.port_type[i+1] 
== MLX4_PORT_TYPE_IB) {<BR>+  if ((dev->caps.port_type[i+1] == 
MLX4_PORT_TYPE_IB) 
||<BR>+            
(dev->caps.port_type[i+1] == 
MLX4_PORT_TYPE_ETH))<BR>+        
{<BR>    count++;<BR>   }<BR>  }<BR>@@ 
-170,6 +172,16 @@<BR>  return FALSE;<BR> }<BR> <BR>+static 
void mlx4_set_port_mask(struct mlx4_dev *dev)<BR>+{<BR>+ int 
i;<BR>+<BR>+ dev->caps.port_mask = 0;<BR>+ for (i = 1; i <= 
dev->caps.num_ports; ++i)<BR>+  if (dev->caps.port_type[i] == 
MLX4_PORT_TYPE_IB)<BR>+   dev->caps.port_mask |= 1 << (i 
- 1);<BR>+}<BR>+<BR> static int mlx4_dev_cap(struct mlx4_dev *dev, struct 
mlx4_dev_cap *dev_cap)<BR> {<BR>  int err;<BR>@@ -309,6 +321,8 
@@<BR>    ++num_eth_ports;<BR>  }<BR> <BR>+ mlx4_set_port_mask(dev);<BR>+<BR>  dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FW] 

dev_cap->reserved_qps;<BR>  dev->caps.reserved_qps_cnt[MLX4_QP_REGION_ETH_ADDR] 
=<BR>   dev->caps.reserved_qps_cnt[MLX4_QP_REGION_FC_ADDR] 
=<BR>Index: 
hw/mlx4/kernel/bus/net/port.c<BR>===================================================================<BR>--- 
hw/mlx4/kernel/bus/net/port.c (revision 2617)<BR>+++ 
hw/mlx4/kernel/bus/net/port.c (working copy)<BR>@@ -33,7 +33,9 
@@<BR> <BR> #include "mlx4.h"<BR> #include "cmd.h"<BR>+#include 
"public.h"<BR> <BR>+extern NTSTATUS 
__create_child();<BR> <BR> void mlx4_init_mac_table(struct mlx4_dev 
*dev, u8 port)<BR> {<BR>@@ -60,6 +62,10 
@@<BR>   table->refs[i] = 
0;<BR>  }<BR>  table->max = 1 << 
dev->caps.log_num_vlans;<BR>+ if(table->max > 
MLX4_MAX_VLAN_NUM)<BR>+ {<BR>+  table->max = 
MLX4_MAX_VLAN_NUM;<BR>+ }<BR>  table->total = 
0;<BR> }<BR> <BR>@@ -84,6 +90,52 @@<BR>  return 
err;<BR> }<BR> <BR>+static void mlx4_addrconf_ifid_eui48_win(u8 *eui, 
u64 mac)<BR>+{<BR>+    u8 *p = (u8*)&mac+2; //mac 6 
bytes<BR>+ memcpy(eui, p, 3);<BR>+ memcpy(eui + 5, p + 3, 
3);<BR>+ eui[3] = 0xFF;<BR>+ eui[4] = 0xFE;<BR>+ eui[0] ^= 
2;<BR>+}<BR>+<BR>+<BR>+static int update_ipv6_gids_win(struct mlx4_dev *dev, int 
port, int clear, u64 mac)<BR>+{<BR>+ struct mlx4_cmd_mailbox 
*mailbox;<BR>+ union ib_gid *gids, *tmpgids;<BR>+ int 
err;<BR>+<BR>+ tmpgids = kzalloc(128 * sizeof *gids, 
GFP_ATOMIC);<BR>+ if (!tmpgids)<BR>+  return 
-ENOMEM;<BR>+<BR>+ if (!clear) 
{<BR>+  mlx4_addrconf_ifid_eui48_win(&tmpgids[0].raw[8], 
cpu_to_be64(mac));<BR>+  tmpgids[0].global.subnet_prefix = 
cpu_to_be64(0xfe80000000000000LL);<BR>+ }<BR>+<BR>+ mailbox = 
mlx4_alloc_cmd_mailbox(dev);<BR>+ if (IS_ERR(mailbox)) 
{<BR>+  err = PTR_ERR(mailbox);<BR>+  goto 
out;<BR>+ }<BR>+<BR>+ gids = mailbox->buf;<BR>+ memcpy(gids, 
tmpgids, 128 * sizeof *gids);<BR>+<BR>+ err = mlx4_cmd(dev, 
mailbox->dma.da, MLX4_SET_PORT_GID_TABLE << 8 | 
port,<BR>+         1, MLX4_CMD_SET_PORT, 
MLX4_CMD_TIME_CLASS_B);<BR>+<BR>+ mlx4_free_cmd_mailbox(dev, 
mailbox);<BR>+<BR>+out:<BR>+ kfree(tmpgids);<BR>+ return 
err;<BR>+}<BR>+<BR>+<BR> int mlx4_register_mac(struct mlx4_dev *dev, u8 
port, u64 mac, int *index)<BR> {<BR>  struct mlx4_mac_table 
*table =<BR>@@ -112,7 +164,7 @@<BR>  }<BR>  mlx4_dbg(dev, 
"Free mac index is %d\n", free);<BR> <BR>- if (table->total == 
table->max) {<BR>+ if (table->total == table->max || free < 0) 
{<BR>   /* No free mac entries */<BR>   err = 
-ENOSPC;<BR>   goto out;<BR>@@ -132,6 +184,20 
@@<BR> <BR>  *index = 
free;<BR>  ++table->total;<BR>+<BR>+ //update port guid with 
mac address<BR>+ update_ipv6_gids_win(dev, port, 0, mac);<BR>+   
<BR>+ if(!InterlockedExchange(&dev->pdev->ib_hca_created, 
1))<BR>+ {<BR>+     NTSTATUS status = 
STATUS_SUCCESS;<BR>+  status = 
__create_child(dev->pdev->p_wdf_device, BUS_HARDWARE_IDS, 
BUS_HARDWARE_DESCRIPTION, 0 );<BR>+  if (!NT_SUCCESS(status)) 
{<BR>+    mlx4_err(dev, "__create_child (ib)failed with 0x%x\n", 
status);<BR>+    dev->pdev->ib_hca_created = 
FALSE;<BR>+  }<BR>+ }<BR>+<BR> out:<BR>  up(&table->mac_sem);<BR>  return 
err;<BR>@@ -207,7 +273,7 
@@<BR>   }<BR>  }<BR> <BR>- if 
(table->total == table->max) {<BR>+ if (table->total == 
table->max || free < 0) {<BR>   /* No free vlan entries 
*/<BR>   err = -ENOSPC;<BR>   goto out;<BR>Index: 
hw/mlx4/kernel/bus/net/SOURCES<BR>===================================================================<BR>--- 
hw/mlx4/kernel/bus/net/SOURCES (revision 2617)<BR>+++ 
hw/mlx4/kernel/bus/net/SOURCES (working copy)<BR>@@ -31,7 +31,7 
@@<BR>  srq.c   \<BR>         
port.c                  
\<BR> <BR>-INCLUDES=..;..\inc;..\..\inc;..\core\$O;..\..\..\..\..\inc;..\..\..\..\..\inc\kernel;<BR>+INCLUDES=..;..\inc;..\..\inc;..\..\..\inc;..\core\$O;..\..\..\..\..\inc;..\..\..\..\..\inc\kernel;<BR> <BR> C_DEFINES=$(C_DEFINES) 
-DDRIVER -DDEPRECATE_DDK_FUNCTIONS -D__LITTLE_ENDIAN -DUSE_WDM_INTERRUPTS 
<BR> #-DFORCE_LIVEFISH<BR>Index: 
hw/mlx4/kernel/hca/av.c<BR>===================================================================<BR>--- 
hw/mlx4/kernel/hca/av.c (revision 2617)<BR>+++ 
hw/mlx4/kernel/hca/av.c (working copy)<BR>@@ -74,6 +74,7 
@@<BR>  p_ib_ah = p_ib_pd->device->create_ah(p_ib_pd, 
&ah_attr);<BR>  if (IS_ERR(p_ib_ah)) {<BR>   err = 
PTR_ERR(p_ib_ah);<BR>+  status = 
errno_to_iberr(err);<BR>   HCA_PRINT(TRACE_LEVEL_ERROR,HCA_DBG_AV 
,("create_ah failed (%d)\n", err));<BR>   goto 
err_create_ah;<BR>  }<BR>Index: 
hw/mlx4/kernel/hca/data.c<BR>===================================================================<BR>--- 
hw/mlx4/kernel/hca/data.c (revision 2617)<BR>+++ 
hw/mlx4/kernel/hca/data.c (working copy)<BR>@@ -339,6 +339,7 
@@<BR>    ibal_port_p->max_vls    = 
mthca_port_p->max_vl_num;<BR>    ibal_port_p->sm_lid     

cl_ntoh16(mthca_port_p->sm_lid);<BR>    ibal_port_p->sm_sl      
= mthca_port_p->sm_sl;<BR>+   ibal_port_p->transport  

mthca_port_p->transport;<BR>    ibal_port_p->link_state 
= (mthca_port_p->state != 0) ? (uint8_t)mthca_port_p->state : 
IB_LINK_DOWN;<BR>    ibal_port_p->num_gids   = 
(uint16_t)mthca_port_p->gid_tbl_len;<BR>    ibal_port_p->num_pkeys  
= mthca_port_p->pkey_tbl_len;<BR>Index: 
hw/mlx4/kernel/inc/l2w.h<BR>===================================================================<BR>--- 
hw/mlx4/kernel/inc/l2w.h (revision 2617)<BR>+++ 
hw/mlx4/kernel/inc/l2w.h (working copy)<BR>@@ -185,6 +185,8 
@@<BR>  DMA_ADAPTER  *    p_dma_adapter; /* 
HCA adapter object 
*/<BR>  DEVICE_OBJECT *    p_self_do;  /* 
mlx4_bus's FDO 
*/<BR>  DEVICE_OBJECT *    pdo;   /* 
mlx4_bus's PDO 
*/<BR>+ PVOID                           
p_wdf_device;   /* wdf_device 
*/<BR>+ LONG       ib_hca_created;<BR>  // 
mlx4_ib: various objects and info <BR>  struct ib_device 
*    ib_dev;<BR>  // mlx4_net: various objects and 
info <BR>Index: 
inc/iba/ib_types.h<BR>===================================================================<BR>--- 
inc/iba/ib_types.h (revision 2617)<BR>+++ inc/iba/ib_types.h (working 
copy)<BR>@@ -9419,6 +9419,8 
@@<BR>  TO_LONG_PTR(ib_gid_t*, p_gid_table);<BR>  TO_LONG_PTR(ib_net16_t*,p_pkey_table);<BR> <BR>+ enum 
rdma_transport_type transport;<BR>+<BR> } ib_port_attr_t;<BR> /*<BR> * 
SEE ALSO<BR>Index: 
ulp/opensm/user/include/iba/ib_types.h<BR>===================================================================<BR>--- 
ulp/opensm/user/include/iba/ib_types.h (revision 2617)<BR>+++ 
ulp/opensm/user/include/iba/ib_types.h (working copy)<BR>@@ -8676,6 +8676,7 
@@<BR>  ib_gid_t    *p_gid_table;<BR>  ib_net16_t    *p_pkey_table;<BR> <BR>+ enum 
rdma_transport_type transport;<BR> } ib_port_attr_t;<BR> /*<BR> * 
SEE ALSO<BR>Index: 
ulp/opensm/user/include/iba/ib_types_extended.h<BR>===================================================================<BR>--- 
ulp/opensm/user/include/iba/ib_types_extended.h (revision 2617)<BR>+++ 
ulp/opensm/user/include/iba/ib_types_extended.h (working copy)<BR>@@ -586,6 
+586,7 
@@<BR>  TO_LONG_PTR(ib_gid_t*, p_gid_table);<BR>  TO_LONG_PTR(ib_net16_t*,p_pkey_table);<BR> <BR>+ enum 
rdma_transport_type transport;<BR> } ib_port_attr_t;<BR> /*<BR> * 
SEE ALSO<BR></DIV></SPAN></FONT></BODY></HTML>