<!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><SPAN class=627183917-21012010><FONT color=#0000ff size=2 face=Arial>Hi 
James,</FONT></SPAN></DIV>
<DIV><SPAN class=627183917-21012010><FONT color=#0000ff size=2 
face=Arial></FONT></SPAN> </DIV>
<DIV><SPAN class=627183917-21012010><FONT color=#0000ff size=2 face=Arial>I'm 
currently working on some urgent issue so I don't have time to look at it right 
now.</FONT></SPAN></DIV>
<DIV><SPAN class=627183917-21012010><FONT color=#0000ff size=2 
face=Arial></FONT></SPAN> </DIV>
<DIV><SPAN class=627183917-21012010><FONT color=#0000ff size=2 face=Arial>In any 
case, please note that I'm looking for a solution that will allow people to have 
3 modes of work:</FONT></SPAN></DIV>
<DIV><SPAN class=627183917-21012010><FONT color=#0000ff size=2 face=Arial>eth 
only</FONT></SPAN></DIV>
<DIV><SPAN class=627183917-21012010><FONT color=#0000ff size=2 face=Arial>ib 
only</FONT></SPAN></DIV>
<DIV><SPAN class=627183917-21012010><FONT color=#0000ff size=2 face=Arial>LLE - 
which actually means that eth as well as IB will work (IB over eth 
though).</FONT></SPAN></DIV>
<DIV><SPAN class=627183917-21012010><FONT color=#0000ff size=2 
face=Arial></FONT></SPAN> </DIV>
<DIV><SPAN class=627183917-21012010><FONT color=#0000ff size=2 face=Arial>This 
is the reason that I have also put the code in mlx4_register_mac under comment 
as well.</FONT></SPAN></DIV>
<DIV><SPAN class=627183917-21012010><FONT color=#0000ff size=2 
face=Arial></FONT></SPAN> </DIV>
<DIV><SPAN class=627183917-21012010><FONT color=#0000ff size=2 
face=Arial>Thanks</FONT></SPAN></DIV>
<DIV><SPAN class=627183917-21012010><FONT color=#0000ff size=2 
face=Arial>Tzachi</FONT></SPAN></DIV><BR>
<BLOCKQUOTE 
style="BORDER-LEFT: #0000ff 2px solid; PADDING-LEFT: 5px; MARGIN-LEFT: 5px; MARGIN-RIGHT: 0px" 
dir=ltr>
  <DIV dir=ltr lang=en-us class=OutlookMessageHeader align=left>
  <HR tabIndex=-1>
  <FONT size=2 face=Tahoma><B>From:</B> James Yang [mailto:jyang@xsigo.com] 
  <BR><B>Sent:</B> Tuesday, January 19, 2010 8:37 PM<BR><B>To:</B> Tzachi Dar; 
  ofw@lists.openfabrics.org<BR><B>Subject:</B> RE: [ofw] patch 1/2 Add support 
  for RDMAoEth to the low level driver<BR></FONT><BR></DIV>
  <DIV></DIV>
  <DIV dir=ltr align=left><SPAN class=443521818-19012010><FONT color=#0000ff 
  size=2 face=Arial>Need the following patch so that it will also work on IB 
  mode. HCA pdo was created twice in the old patch and failed driver start 
  up.</FONT></SPAN></DIV>
  <DIV dir=ltr align=left><SPAN class=443521818-19012010><FONT color=#0000ff 
  size=2 face=Arial></FONT></SPAN> </DIV>
  <DIV dir=ltr align=left><SPAN class=443521818-19012010><FONT color=#0000ff 
  size=2 face=Arial>By the way, it seems ipoib didn't work well at least in 
  win2008 with the patch. Interface mismatch?</FONT></SPAN></DIV>
  <DIV dir=ltr align=left><SPAN class=443521818-19012010><FONT color=#0000ff 
  size=2 face=Arial></FONT></SPAN> </DIV>
  <DIV dir=ltr align=left><SPAN class=443521818-19012010><FONT color=#0000ff 
  size=2 face=Arial>Thanks,</FONT></SPAN></DIV>
  <DIV dir=ltr align=left><SPAN class=443521818-19012010><FONT color=#0000ff 
  size=2 face=Arial>James</FONT></SPAN></DIV>
  <DIV dir=ltr align=left><SPAN class=443521818-19012010><FONT color=#0000ff 
  size=2 face=Arial></FONT></SPAN> </DIV>
  <DIV dir=ltr align=left><SPAN class=443521818-19012010><FONT color=#0000ff 
  size=2 face=Arial>Index: 
  drv.c<BR>===================================================================<BR>--- 
  drv.c (revision 2617)<BR>+++ 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,7 +227,7 @@<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>@@ -244,6 +243,16 
  @@<BR>                      
  break;<BR>                 
  }<BR>                 
  eth_created = 
  TRUE;<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>+       
  break;<BR>+     }<BR>+     ib_created 
  = 
  TRUE;<BR>+    }<BR>             
  } else 
  {<BR>                 
  if 
  (eth_created){<BR>                     
  //<BR>@@ -869,6 +878,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></FONT></SPAN></DIV><BR>
  <DIV dir=ltr lang=en-us class=OutlookMessageHeader align=left>
  <HR tabIndex=-1>
  <FONT size=2 face=Tahoma><B>From:</B> ofw-bounces@lists.openfabrics.org 
  [mailto:ofw-bounces@lists.openfabrics.org] <B>On Behalf Of </B>Tzachi 
  Dar<BR><B>Sent:</B> Wednesday, December 02, 2009 8:22 AM<BR><B>To:</B> 
  ofw@lists.openfabrics.org<BR><B>Subject:</B> [ofw] patch 1/2 Add support for 
  RDMAoEth to the low level driver<BR></FONT><BR></DIV>
  <DIV></DIV>
  <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></BLOCKQUOTE></SPAN></FONT></BODY></HTML>