|
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 (brad
comstyle.com)
Date: Fri Dec 22 2006 - 21:20:16 CST
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
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 thorpej
NetBSD
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);
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]