[IPoIB] Fix multicast send support to not drop packets if the adapter
[mirror/winof/.git] / ulp / ipoib / kernel / ipoib_port.c
index cbd5f9d..8f01cc9 100644 (file)
@@ -755,7 +755,7 @@ __ib_mgr_init(
 \r
        /* Allocate the PD. */\r
        status = p_port->p_adapter->p_ifc->alloc_pd(\r
-               p_port->ib_mgr.h_ca, IB_PDT_NORMAL, p_port, &p_port->ib_mgr.h_pd );\r
+               p_port->ib_mgr.h_ca, IB_PDT_UD, p_port, &p_port->ib_mgr.h_pd );\r
        if( status != IB_SUCCESS )\r
        {\r
                IPOIB_TRACE_EXIT( IPOIB_DBG_ERROR,\r
@@ -1674,6 +1674,17 @@ __recv_get_endpts(
                CL_ASSERT( *pp_dst );\r
        }\r
 \r
+       IPOIB_TRACE( (IPOIB_DBG_RECV | IPOIB_DBG_INFO),\r
+               ("Recv:\n"\r
+               "\tsrc MAC: %02X-%02X-%02X-%02X-%02X-%02X\n"\r
+               "\tdst MAC: %02X-%02X-%02X-%02X-%02X-%02X\n",\r
+               (*pp_src )->mac.addr[0], (*pp_src )->mac.addr[1],\r
+               (*pp_src )->mac.addr[2], (*pp_src )->mac.addr[3],\r
+               (*pp_src )->mac.addr[4], (*pp_src )->mac.addr[5],\r
+               (*pp_dst )->mac.addr[0], (*pp_dst )->mac.addr[1],\r
+               (*pp_dst )->mac.addr[2], (*pp_dst )->mac.addr[3],\r
+               (*pp_dst )->mac.addr[4], (*pp_dst )->mac.addr[5]) );\r
+\r
        IPOIB_EXIT( IPOIB_DBG_RECV );\r
 }\r
 \r
@@ -1754,6 +1765,20 @@ __recv_mgr_filter(
                p_eth = &p_desc->p_buf->eth.pkt;\r
 #endif /*IPOIB_INLINE_RECV */\r
 \r
+               /* Don't report loopback traffic - we requested SW loopback. */\r
+               if( !cl_memcmp( &p_port->p_adapter->mac, &p_eth->hdr.src,\r
+                       sizeof(p_port->p_adapter->mac) ) )\r
+               {\r
+                       /*\r
+                        * "This is not the packet you're looking for" - don't update\r
+                        * receive statistics, the packet never happened.\r
+                        */\r
+                       cl_qlist_insert_tail( p_bad_list, &p_desc->item.list_item );\r
+                       /* Dereference the port object on behalf of the failed receive. */\r
+                       cl_obj_deref( &p_port->obj );\r
+                       continue;\r
+               }\r
+\r
                switch( p_ipoib->hdr.type )\r
                {\r
                case ETH_PROT_TYPE_IP:\r
@@ -1921,6 +1946,8 @@ __recv_dhcp(
 \r
        IPOIB_ENTER( IPOIB_DBG_RECV );\r
 \r
+       UNUSED_PARAM( p_port );\r
+\r
        /* Create the ethernet header. */\r
        status = __recv_gen( p_ipoib, p_eth, p_src, p_dst );\r
        if( status != IB_SUCCESS )\r
@@ -1938,17 +1965,6 @@ __recv_dhcp(
                IPOIB_TRACE_EXIT( IPOIB_DBG_ERROR, ("Invalid DHCP op code.\n") );\r
                return IB_INVALID_SETTING;\r
        }\r
-       /* find a better way to check for echo packets ? */\r
-       if ( p_port->p_adapter->mac.addr[0] == p_eth->hdr.src.addr[0] &&\r
-                p_port->p_adapter->mac.addr[1] == p_eth->hdr.src.addr[1] &&\r
-                p_port->p_adapter->mac.addr[2] == p_eth->hdr.src.addr[2] &&\r
-                p_port->p_adapter->mac.addr[3] == p_eth->hdr.src.addr[3] &&\r
-                p_port->p_adapter->mac.addr[4] == p_eth->hdr.src.addr[4] &&\r
-                p_port->p_adapter->mac.addr[5] == p_eth->hdr.src.addr[5] )\r
-       {\r
-               IPOIB_TRACE_EXIT( IPOIB_DBG_ERROR, ("Local echo dhcp msg.\n") );\r
-               return IB_INVALID_PARAMETER;\r
-       }\r
 \r
        /*\r
         * Find the client identifier option, making sure to skip\r
@@ -3289,6 +3305,19 @@ __send_mgr_queue(
        status = __endpt_mgr_ref( p_port, p_eth_hdr->dst, pp_endpt );\r
        cl_perf_stop( &p_port->p_adapter->perf, GetEndpt );\r
 \r
+       if( status == NDIS_STATUS_NO_ROUTE_TO_DESTINATION &&\r
+               p_eth_hdr->dst.addr[0] == 0x01 &&\r
+               p_eth_hdr->dst.addr[1] == 0x00 &&\r
+               p_eth_hdr->dst.addr[2] == 0x5E )\r
+       {\r
+               if( ipoib_port_join_mcast( p_port, p_eth_hdr->dst ) == IB_SUCCESS )\r
+               {\r
+                       IPOIB_TRACE_EXIT( IPOIB_DBG_ENDPT,\r
+                               ("Multicast Mac - trying to join.\n") );\r
+                       return NDIS_STATUS_PENDING;\r
+               }\r
+       }\r
+\r
        IPOIB_EXIT( IPOIB_DBG_SEND );\r
        return status;\r
 }\r
@@ -3405,6 +3434,7 @@ ipoib_port_send(
 \r
        IPOIB_ENTER( IPOIB_DBG_SEND );\r
 \r
+       cl_spinlock_acquire( &p_port->send_lock );\r
        for( i = 0; i < num_packets; i++ )\r
        {\r
                desc.p_pkt = p_packet_array[i];\r
@@ -3424,7 +3454,6 @@ ipoib_port_send(
                        continue;\r
                }\r
 \r
-               cl_spinlock_acquire( &p_port->send_lock );\r
                cl_perf_start( SendMgrQueue );\r
                status = __send_mgr_queue( p_port, p_eth_hdr, &desc.p_endpt );\r
                cl_perf_stop( &p_port->p_adapter->perf, SendMgrQueue );\r
@@ -3438,10 +3467,8 @@ ipoib_port_send(
                                        IPOIB_LIST_ITEM_FROM_PACKET( p_packet_array[i++] ) );\r
                        }\r
                        cl_perf_stop( &p_port->p_adapter->perf, QueuePacket );\r
-                       cl_spinlock_release( &p_port->send_lock );\r
-                       return;\r
+                       break;\r
                }\r
-               cl_spinlock_release( &p_port->send_lock );\r
                if( status != NDIS_STATUS_SUCCESS )\r
                {\r
                        ASSERT( status == NDIS_STATUS_NO_ROUTE_TO_DESTINATION );\r
@@ -3455,7 +3482,6 @@ ipoib_port_send(
                        continue;\r
                }\r
 \r
-               /* No lock needed to build the work request. */\r
                cl_perf_start( BuildSendDesc );\r
                status = __build_send_desc( p_port, p_eth_hdr, p_buf, buf_len, &desc );\r
                cl_perf_stop( &p_port->p_adapter->perf, BuildSendDesc );\r
@@ -3486,6 +3512,7 @@ ipoib_port_send(
 \r
                cl_atomic_inc( &p_port->send_mgr.depth );\r
        }\r
+       cl_spinlock_release( &p_port->send_lock );\r
 \r
        IPOIB_EXIT( IPOIB_DBG_SEND );\r
 }\r
@@ -3552,6 +3579,22 @@ ipoib_port_resume(
                else if( status != NDIS_STATUS_SUCCESS )\r
                {\r
                        ASSERT( status == NDIS_STATUS_NO_ROUTE_TO_DESTINATION );\r
+\r
+                       if( p_eth_hdr->dst.addr[0] == 0x01 &&\r
+                               p_eth_hdr->dst.addr[1] == 0x00 &&\r
+                               p_eth_hdr->dst.addr[2] == 0x5E )\r
+                       {\r
+                               if( ipoib_port_join_mcast( p_port, p_eth_hdr->dst ) ==\r
+                                       IB_SUCCESS )\r
+                               {\r
+                                       IPOIB_TRACE_EXIT( IPOIB_DBG_ENDPT,\r
+                                               ("Multicast Mac - trying to join.\n") );\r
+                                       cl_qlist_insert_head( &p_port->send_mgr.pending_list,\r
+                                               IPOIB_LIST_ITEM_FROM_PACKET( desc.p_pkt ) );\r
+                                       break;\r
+                               }\r
+                       }\r
+\r
                        /*\r
                         * Complete the send as if we sent it - WHQL tests don't like the\r
                         * sends to fail.\r
@@ -3873,6 +3916,11 @@ __endpt_mgr_ref(
 \r
        cl_obj_lock( &p_port->obj );\r
 \r
+       IPOIB_TRACE( (IPOIB_DBG_ENDPT | IPOIB_DBG_INFO),\r
+               ("Look for :\t  MAC: %02X-%02X-%02X-%02X-%02X-%02X\n",\r
+               mac.addr[0], mac.addr[1], mac.addr[2],\r
+               mac.addr[3], mac.addr[4], mac.addr[5]) );\r
+\r
        p_item = cl_qmap_get( &p_port->endpt_mgr.mac_endpts, key );\r
        if( p_item == cl_qmap_end( &p_port->endpt_mgr.mac_endpts ) )\r
        {\r
@@ -3985,6 +4033,11 @@ __endpt_mgr_insert_locked(
 {\r
        IPOIB_ENTER( IPOIB_DBG_ENDPT );\r
 \r
+       IPOIB_TRACE( (IPOIB_DBG_ENDPT | IPOIB_DBG_INFO),\r
+               ("insert  :\t  MAC: %02X-%02X-%02X-%02X-%02X-%02X\n",\r
+               mac.addr[0], mac.addr[1], mac.addr[2],\r
+               mac.addr[3], mac.addr[4], mac.addr[5]) );\r
+\r
        cl_obj_lock( &p_port->obj );\r
        while( p_port->endpt_rdr )\r
        {\r
@@ -4863,6 +4916,19 @@ ipoib_port_join_mcast(
 \r
        IPOIB_ENTER( IPOIB_DBG_MCAST );\r
 \r
+       switch( __endpt_mgr_ref( p_port, mac, &p_endpt ) )\r
+       {\r
+       case NDIS_STATUS_NO_ROUTE_TO_DESTINATION:\r
+               break;\r
+\r
+       case NDIS_STATUS_SUCCESS:\r
+               ipoib_endpt_deref( p_endpt );\r
+               /* Fall through */\r
+\r
+       case NDIS_STATUS_PENDING:\r
+               return IB_SUCCESS;\r
+       }\r
+\r
        /*\r
         * Issue the mcast request, using the parameters of the broadcast group.\r
         * This allows us to do a create request that should always succeed since\r
@@ -5027,6 +5093,10 @@ __mcast_cb(
                CL_ASSERT( p_qitem == &p_endpt->lid_item );\r
        }\r
        cl_obj_unlock( &p_port->obj );\r
+       \r
+       /* Try to send all pending sends. */\r
+       ipoib_port_resume( p_port );\r
+\r
        cl_obj_deref( &p_port->obj );\r
 \r
        IPOIB_EXIT( IPOIB_DBG_MCAST );\r