OSEC

Neohapsis is currently accepting applications for employment. For more information, please visit our website www.neohapsis.com or email hr@neohapsis.com
 
diff for an issue with pcn(4) running under VMware.

From: Brad (bradcomstyle.com)
Date: Fri Dec 22 2006 - 21:20:16 CST


If you're using VMware and using the pcn(4) interface then please
test the following diff.

Detect if we're talking to a VMware virtual interface, and, if so,
limit the number of Tx segments to 8 to work around a VMware bug.

From thorpejNetBSD

Index: if_pcn.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_pcn.c,v
retrieving revision 1.15
diff -u -p -r1.15 if_pcn.c
--- if_pcn.c 9 Nov 2006 14:25:23 -0000 1.15
+++ if_pcn.c 26 Nov 2006 02:48:36 -0000
-163,6 +163,7 __KERNEL_RCSID(0, "$NetBSD: if_pcn.c,v 1
  * transmit logic can deal with this, we just are hoping to sneak by.
  */
 #define PCN_NTXSEGS 16
+#define PCN_NTXSEGS_VMWARE 8 /* bug in VMware's emulation */
 
 #define PCN_TXQUEUELEN 128
 #define PCN_TXQUEUELEN_MASK (PCN_TXQUEUELEN - 1)
-533,6 +534,26 pcn_bcr_write(struct pcn_softc *sc, int
         bus_space_write_4(sc->sc_st, sc->sc_sh, PCN32_BDP, val);
 }
 
+static int
+pcn_is_vmware(const char *enaddr)
+{
+ /*
+ * VMware uses the OUI 00:0c:29 for auto-generated MAC
+ * addresses.
+ */
+ if (enaddr[0] == 0x00 && enaddr[1] == 0x0c && enaddr[2] == 0x29)
+ return (1);
+
+ /*
+ * VMware uses the OUI 00:50:56 for manually-set MAC
+ * addresses (and some auto-generated ones).
+ */
+ if (enaddr[0] == 0x00 && enaddr[1] == 0x50 && enaddr[2] == 0x56)
+ return (1);
+
+ return (0);
+}
+
 static const struct pcn_variant *
 pcn_lookup_variant(uint16_t chipid)
 {
-583,7 +604,7 pcn_attach(struct device *parent, struct
         bus_space_handle_t ioh, memh;
         bus_dma_segment_t seg;
         int ioh_valid, memh_valid;
- int i, rseg, error;
+ int ntxsegs, is_vmware, i, rseg, error;
         pcireg_t pmode;
         uint32_t chipid, reg;
         uint8_t enaddr[ETHER_ADDR_LEN];
-662,6 +683,9 pcn_attach(struct device *parent, struct
         }
 #endif
 
+ /* Check to see if this is a VMware emulated network interface. */
+ is_vmware = pcn_is_vmware(enaddr);
+
         /*
          * Now that the device is mapped, attempt to figure out what
          * kind of chip we have. Note that IDL has all 32 bits of
-671,6 +695,15 pcn_attach(struct device *parent, struct
         sc->sc_variant = pcn_lookup_variant(CHIPID_PARTID(chipid));
 
         /*
+ * VMware has a bug in its network interface emulation; we must
+ * limit the number of Tx segments.
+ */
+ if (is_vmware)
+ ntxsegs = PCN_NTXSEGS_VMWARE;
+ else
+ ntxsegs = PCN_NTXSEGS;
+
+ /*
          * Map and establish our interrupt.
          */
         if (pci_intr_map(pa, &ih)) {
-727,7 +760,7 pcn_attach(struct device *parent, struct
         /* Create the transmit buffer DMA maps. */
         for (i = 0; i < PCN_TXQUEUELEN; i++) {
                 if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES,
- PCN_NTXSEGS, MCLBYTES, 0, 0,
+ ntxsegs, MCLBYTES, 0, 0,
                      &sc->sc_txsoft[i].txs_dmamap)) != 0) {
                         printf(": unable to create tx DMA map %d, "
                             "error = %d\n", i, error);