Author: jfv
Date: Tue Sep  7 20:13:08 2010
New Revision: 212303
URL: http://svn.freebsd.org/changeset/base/212303

Log:
  Tighten up the rx mbuf refresh code, there were some
  discrepencies from the igb version which was the target.
  
  Change the message when neither MSI or MSIX are enabled
  and a fallback to Legacy interrupts happen, the existing
  message was confusing.

Modified:
  head/sys/dev/e1000/if_em.c
  head/sys/dev/e1000/if_em.h

Modified: head/sys/dev/e1000/if_em.c
==============================================================================
--- head/sys/dev/e1000/if_em.c  Tue Sep  7 18:29:29 2010        (r212302)
+++ head/sys/dev/e1000/if_em.c  Tue Sep  7 20:13:08 2010        (r212303)
@@ -93,7 +93,7 @@ int   em_display_debug_stats = 0;
 /*********************************************************************
  *  Driver version:
  *********************************************************************/
-char em_driver_version[] = "7.0.5";
+char em_driver_version[] = "7.0.6";
 
 
 /*********************************************************************
@@ -281,6 +281,8 @@ static void em_handle_link(void *context
 static void    em_add_rx_process_limit(struct adapter *, const char *,
                    const char *, int *, int);
 
+static __inline void em_rx_discard(struct rx_ring *, int);
+
 #ifdef DEVICE_POLLING
 static poll_handler_t em_poll;
 #endif /* POLLING */
@@ -2563,11 +2565,11 @@ msi:
                val = pci_msi_count(dev);
                if (val == 1 && pci_alloc_msi(dev, &val) == 0) {
                        adapter->msix = 1;
-                       device_printf(adapter->dev,"Using MSI interrupt\n");
+                       device_printf(adapter->dev,"Using an MSI interrupt\n");
                return (val);
        } 
-       /* Should only happen due to manual invention */
-       device_printf(adapter->dev,"Setup MSIX failure\n");
+       /* Should only happen due to manual configuration */
+       device_printf(adapter->dev,"No MSI/MSIX using a Legacy IRQ\n");
        return (0);
 }
 
@@ -3681,14 +3683,27 @@ em_refresh_mbufs(struct rx_ring *rxr, in
        struct adapter          *adapter = rxr->adapter;
        struct mbuf             *m;
        bus_dma_segment_t       segs[1];
-       bus_dmamap_t            map;
        struct em_buffer        *rxbuf;
        int                     i, error, nsegs, cleaned;
 
        i = rxr->next_to_refresh;
        cleaned = -1;
        while (i != limit) {
+               rxbuf = &rxr->rx_buffers[i];
+               /*
+               ** Just skip entries with a buffer,
+               ** they can only be due to an error
+               ** and are to be reused.
+               */
+               if (rxbuf->m_head != NULL)
+                       continue;
                m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
+               /*
+               ** If we have a temporary resource shortage
+               ** that causes a failure, just abort refresh
+               ** for now, we will return to this point when
+               ** reinvoked from em_rxeof.
+               */
                if (m == NULL)
                        goto update;
                m->m_len = m->m_pkthdr.len = MCLBYTES;
@@ -3696,11 +3711,8 @@ em_refresh_mbufs(struct rx_ring *rxr, in
                if (adapter->max_frame_size <= (MCLBYTES - ETHER_ALIGN))
                        m_adj(m, ETHER_ALIGN);
 
-               /*
-                * Using memory from the mbuf cluster pool, invoke the
-                * bus_dma machinery to arrange the memory mapping.
-                */
-               error = bus_dmamap_load_mbuf_sg(rxr->rxtag, rxr->rx_sparemap,
+               /* Use bus_dma machinery to setup the memory mapping  */
+               error = bus_dmamap_load_mbuf_sg(rxr->rxtag, rxbuf->map,
                    m, segs, &nsegs, BUS_DMA_NOWAIT);
                if (error != 0) {
                        m_free(m);
@@ -3710,13 +3722,6 @@ em_refresh_mbufs(struct rx_ring *rxr, in
                /* If nsegs is wrong then the stack is corrupt. */
                KASSERT(nsegs == 1, ("Too many segments returned!"));
        
-               rxbuf = &rxr->rx_buffers[i];
-               if (rxbuf->m_head != NULL)
-                       bus_dmamap_unload(rxr->rxtag, rxbuf->map);
-       
-               map = rxbuf->map;
-               rxbuf->map = rxr->rx_sparemap;
-               rxr->rx_sparemap = map;
                bus_dmamap_sync(rxr->rxtag,
                    rxbuf->map, BUS_DMASYNC_PREREAD);
                rxbuf->m_head = m;
@@ -3730,8 +3735,10 @@ em_refresh_mbufs(struct rx_ring *rxr, in
                rxr->next_to_refresh = i;
        }
 update:
-       bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map,
-           BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+       /*
+       ** Update the tail pointer only if,
+       ** and as far as we have refreshed.
+       */
        if (cleaned != -1) /* Update tail index */
                E1000_WRITE_REG(&adapter->hw,
                    E1000_RDT(rxr->me), cleaned);
@@ -3781,15 +3788,6 @@ em_allocate_receive_buffers(struct rx_ri
                goto fail;
        }
 
-       /* Create the spare map (used by getbuf) */
-       error = bus_dmamap_create(rxr->rxtag, BUS_DMA_NOWAIT,
-            &rxr->rx_sparemap);
-       if (error) {
-               device_printf(dev, "%s: bus_dmamap_create failed: %d\n",
-                   __func__, error);
-               goto fail;
-       }
-
        rxbuf = rxr->rx_buffers;
        for (int i = 0; i < adapter->num_rx_desc; i++, rxbuf++) {
                rxbuf = &rxr->rx_buffers[i];
@@ -3956,11 +3954,6 @@ em_free_receive_buffers(struct rx_ring *
 
        INIT_DEBUGOUT("free_receive_buffers: begin");
 
-       if (rxr->rx_sparemap) {
-               bus_dmamap_destroy(rxr->rxtag, rxr->rx_sparemap);
-               rxr->rx_sparemap = NULL;
-       }
-
        if (rxr->rx_buffers != NULL) {
                for (int i = 0; i < adapter->num_rx_desc; i++) {
                        rxbuf = &rxr->rx_buffers[i];
@@ -4132,12 +4125,16 @@ em_rxeof(struct rx_ring *rxr, int count,
                eop = (status & E1000_RXD_STAT_EOP) != 0;
                count--;
 
-               if ((cur->errors & E1000_RXD_ERR_FRAME_ERR_MASK) == 0) {
+               if (((cur->errors & E1000_RXD_ERR_FRAME_ERR_MASK) == 0) &&
+                   (rxr->discard == FALSE)) {
 
                        /* Assign correct length to the current fragment */
                        mp = rxr->rx_buffers[i].m_head;
                        mp->m_len = len;
 
+                       /* Trigger for refresh */
+                       rxr->rx_buffers[i].m_head = NULL;
+
                        if (rxr->fmp == NULL) {
                                mp->m_pkthdr.len = len;
                                rxr->fmp = mp; /* Store the first mbuf */
@@ -4179,19 +4176,12 @@ skip:
                        }
                } else {
                        ifp->if_ierrors++;
-                       /* Reuse loaded DMA map and just update mbuf chain */
-                       mp = rxr->rx_buffers[i].m_head;
-                       mp->m_len = mp->m_pkthdr.len = MCLBYTES;
-                       mp->m_data = mp->m_ext.ext_buf;
-                       mp->m_next = NULL;
-                       if (adapter->max_frame_size <=
-                           (MCLBYTES - ETHER_ALIGN))
-                               m_adj(mp, ETHER_ALIGN);
-                       if (rxr->fmp != NULL) {
-                               m_freem(rxr->fmp);
-                               rxr->fmp = NULL;
-                               rxr->lmp = NULL;
-                       }
+                       ++rxr->rx_discarded;
+                       if (!eop) /* Catch subsequent segs */
+                               rxr->discard = TRUE;
+                       else
+                               rxr->discard = FALSE;
+                       em_rx_discard(rxr, i);
                        sendmp = NULL;
                }
 
@@ -4234,6 +4224,31 @@ skip:
        return ((status & E1000_RXD_STAT_DD) ? TRUE : FALSE);
 }
 
+static __inline void
+em_rx_discard(struct rx_ring *rxr, int i)
+{
+       struct em_buffer        *rbuf;
+       struct mbuf             *m;
+
+       rbuf = &rxr->rx_buffers[i];
+       /* Free any previous pieces */
+       if (rxr->fmp != NULL) {
+               rxr->fmp->m_flags |= M_PKTHDR;
+               m_freem(rxr->fmp);
+               rxr->fmp = NULL;
+               rxr->lmp = NULL;
+       }
+                         
+       /* Reset state, keep loaded DMA map and reuse */
+       m = rbuf->m_head;
+       m->m_len = m->m_pkthdr.len = MCLBYTES;
+       m->m_flags |= M_PKTHDR;
+       m->m_data = m->m_ext.ext_buf;
+       m->m_next = NULL;
+
+       return;
+}
+
 #ifndef __NO_STRICT_ALIGNMENT
 /*
  * When jumbo frames are enabled we should realign entire payload on
@@ -5159,8 +5174,6 @@ em_add_hw_stats(struct adapter *adapter)
                        CTLFLAG_RD, &adapter->stats.hrmpc,
                        "Header Redirection Missed Packet Count");
 
-
-
 }
 
 /**********************************************************************
@@ -5170,7 +5183,6 @@ em_add_hw_stats(struct adapter *adapter)
  *  32 words, stuff that matters is in that extent.
  *
  **********************************************************************/
-
 static int
 em_sysctl_nvm_info(SYSCTL_HANDLER_ARGS)
 {

Modified: head/sys/dev/e1000/if_em.h
==============================================================================
--- head/sys/dev/e1000/if_em.h  Tue Sep  7 18:29:29 2010        (r212302)
+++ head/sys/dev/e1000/if_em.h  Tue Sep  7 20:13:08 2010        (r212303)
@@ -320,10 +320,11 @@ struct rx_ring {
         void                    *tag;
         struct resource         *res;
         bus_dma_tag_t           rxtag;
-        bus_dmamap_t            rx_sparemap;
+       bool                    discard;
 
         /* Soft stats */
         unsigned long          rx_irq;
+        unsigned long          rx_discarded;
         unsigned long          rx_packets;
         unsigned long          rx_bytes;
 };
@@ -393,6 +394,7 @@ struct adapter {
 
        /* Multicast array memory */
        u8              *mta;
+
        /* Info about the board itself */
        uint8_t         link_active;
        uint16_t        link_speed;
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to