On Thu, 11 Nov 2004, Robert Watson wrote: > That patch excluded the addition of a new variable to the adapter > structure in if_em.h. Full patch below. FYI I have merged this patch to CVS HEAD; I will merge it to the RELENG_5 branch after it's settled for a few days, and then request permission to merge to the RELENG_5_3 errata branch for inclusion there after further settling and testing. I've had several positive reports back, but would appreciate any additional testing of the change as committed to HEAD. Robert N M Watson FreeBSD Core Team, TrustedBSD Projects robert_at_fledge.watson.org Principal Research Scientist, McAfee Research > ==== //depot/vendor/freebsd/src/sys/dev/em/if_em.c#51 - /zoo/rwatson/p4/vendor/freebsd/src/sys/dev/em/if_em.c ==== > _at__at_ -161,7 +161,7 _at__at_ > static int em_get_buf(int i, struct adapter *, > struct mbuf *); > static void em_enable_vlans(struct adapter *); > -static int em_encap(struct adapter *, struct mbuf *); > +static int em_encap(struct adapter *, struct mbuf **); > static void em_smartspeed(struct adapter *); > static int em_82547_fifo_workaround(struct adapter *, int); > static void em_82547_update_fifo_head(struct adapter *, int); > _at__at_ -616,7 +616,7 _at__at_ > > if (m_head == NULL) break; > > - if (em_encap(adapter, m_head)) { > + if (em_encap(adapter, &m_head)) { > ifp->if_flags |= IFF_OACTIVE; > IFQ_DRV_PREPEND(&ifp->if_snd, m_head); > break; > _at__at_ -1176,13 +1176,15 _at__at_ > * return 0 on success, positive on failure > **********************************************************************/ > static int > -em_encap(struct adapter *adapter, struct mbuf *m_head) > +em_encap(struct adapter *adapter, struct mbuf **m_headp) > { > u_int32_t txd_upper; > u_int32_t txd_lower, txd_used = 0, txd_saved = 0; > int i, j, error; > u_int64_t address; > > + struct mbuf *m_head; > + > /* For 82544 Workaround */ > DESC_ARRAY desc_array; > u_int32_t array_elements; > _at__at_ -1198,6 +1200,8 _at__at_ > struct em_tx_desc *current_tx_desc = NULL; > struct ifnet *ifp = &adapter->interface_data.ac_if; > > + m_head = *m_headp; > + > /* > * Force a cleanup if number of TX descriptors > * available hits the threshold > _at__at_ -1250,6 +1254,36 _at__at_ > mtag = VLAN_OUTPUT_TAG(ifp, m_head); > #endif > > + /* > + * When operating in promiscuous mode, hardware encapsulation for > + * packets is disabled. This means we have to add the vlan > + * encapsulation in the driver, since it will have come down from the > + * VLAN layer with a tag instead of a VLAN header. > + */ > + if (mtag != NULL && adapter->em_vlan_tag_workaround) { > + struct ether_vlan_header *evl; > + struct ether_header eh; > + > + m_head = m_pullup(m_head, sizeof(eh)); > + if (m_head == NULL) > + return (ENOBUFS); > + eh = *mtod(m_head, struct ether_header *); > + M_PREPEND(m_head, sizeof(*evl), M_DONTWAIT); > + if (m_head == NULL) > + return (ENOBUFS); > + m_head = m_pullup(m_head, sizeof(*evl)); > + if (m_head == NULL) > + return (ENOBUFS); > + evl = mtod(m_head, struct ether_vlan_header *); > + bcopy(&eh, evl, sizeof(*evl)); > + evl->evl_proto = evl->evl_encap_proto; > + evl->evl_encap_proto = htons(ETHERTYPE_VLAN); > + evl->evl_tag = htons(VLAN_TAG_VALUE(mtag)); > + m_tag_delete(m_head, mtag); > + mtag = NULL; > + *m_headp = m_head; > + } > + > i = adapter->next_avail_tx_desc; > if (adapter->pcix_82544) { > txd_saved = i; > _at__at_ -1497,19 +1531,20 _at__at_ > if (ifp->if_flags & IFF_PROMISC) { > reg_rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE); > E1000_WRITE_REG(&adapter->hw, RCTL, reg_rctl); > - > /* Disable VLAN stripping in promiscous mode > * This enables bridging of vlan tagged frames to occur > * and also allows vlan tags to be seen in tcpdump > */ > ctrl &= ~E1000_CTRL_VME; > E1000_WRITE_REG(&adapter->hw, CTRL, ctrl); > - > + adapter->em_vlan_tag_workaround = 1; > } else if (ifp->if_flags & IFF_ALLMULTI) { > reg_rctl |= E1000_RCTL_MPE; > reg_rctl &= ~E1000_RCTL_UPE; > E1000_WRITE_REG(&adapter->hw, RCTL, reg_rctl); > - } > + adapter->em_vlan_tag_workaround = 0; > + } else > + adapter->em_vlan_tag_workaround = 0; > > return; > } > _at__at_ -1526,6 +1561,8 _at__at_ > E1000_WRITE_REG(&adapter->hw, RCTL, reg_rctl); > > em_enable_vlans(adapter); > + adapter->em_vlan_tag_workaround = 0; > + > return; > } > > ==== //depot/vendor/freebsd/src/sys/dev/em/if_em.h#26 - /zoo/rwatson/p4/vendor/freebsd/src/sys/dev/em/if_em.h ==== > _at__at_ -346,6 +346,7 _at__at_ > int io_rid; > u_int8_t unit; > struct mtx mtx; > + int em_vlan_tag_workaround; > > /* Info about the board itself */ > u_int32_t part_num; > > >Received on Sat Nov 13 2004 - 11:38:48 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:38:22 UTC