kern/50644: [PATCH] Update xe driver: multicast, hardware setup, etc.

Scott Mitchell scott+freebsd at fishballoon.org
Wed Apr 23 15:00:37 PDT 2003


The following reply was made to PR kern/50644; it has been noted by GNATS.

From: Scott Mitchell <scott+freebsd at fishballoon.org>
To: FreeBSD-gnats-submit at FreeBSD.org
Cc: scott+freebsd at tuatara.fishballoon.org
Subject: Re: kern/50644: [PATCH] Update xe driver: multicast, hardware setup, etc.
Date: Wed, 23 Apr 2003 22:53:54 +0100

 The following patch adds support for CE2 cards to the xe driver.  It works
 for the one such card I have available; I'd be very interested to know if
 anyone else has any luck with it.
 
 The patch should be applied on top of the preceding one.  If, like me,
 you're still stuck using OLDCARD, you'll probably also need the patch in
 kern/51333 (http://www.freebsd.org/cgi/query-pr.cgi?pr=51333).  This forces
 OLDCARD to pass some extra CIS data into the driver, which is needed to
 identify some CE2 cards.
 
 Note that older combo cards such as the CEM28 and CEM33 still won't work.
 I think I have a solution for that, but it needs a bit more work.
 
 	Scott
 
 Index: sys/dev/xe/if_xe.c
 ===================================================================
 RCS file: /home/ncvs/src/sys/dev/xe/if_xe.c,v
 retrieving revision 1.35.10000.3
 diff -u -r1.35.10000.3 if_xe.c
 --- sys/dev/xe/if_xe.c	6 Apr 2003 15:06:24 -0000	1.35.10000.3
 +++ sys/dev/xe/if_xe.c	23 Apr 2003 15:17:07 -0000
 @@ -319,6 +319,7 @@
    scp->tx_tpr = 0;
    scp->tx_timeouts = 0;
    scp->tx_thres = 64;
 +  scp->tx_min = ETHER_MIN_LEN - ETHER_CRC_LEN;
    scp->ifp->if_timer = 0;
  
    /* Soft reset the card */
 @@ -431,7 +432,7 @@
    }
  
  #if XE_DEBUG > 2
 -  device_printf(scp->dev, "start");
 +  device_printf(scp->dev, "start\n");
  #endif
  
    /*
 @@ -702,7 +703,7 @@
        rsr = XE_INB(XE_RSR);
  
  #if XE_DEBUG > 2
 -    device_printf(scp->dev, "intr: ESR=0x%02x, RSR=0x%02x\n", esr, rsr,);
 +    device_printf(scp->dev, "intr: ESR=0x%02x, RSR=0x%02x\n", esr, rsr);
  #endif
  
        /* Make sure packet is a good one */
 @@ -1500,28 +1501,34 @@
   */
  static int
  xe_pio_write_packet(struct xe_softc *scp, struct mbuf *mbp) {
 -  struct mbuf *mbp2;
 -  u_int16_t len, pad, free, ok;
 +  unsigned len, pad;
 +  unsigned char wantbyte;
    u_int8_t *data;
 -  u_int8_t savebyte[2], wantbyte;
 +  u_int8_t savebyte[2];
  
    /* Get total packet length */
 -  for (len = 0, mbp2 = mbp; mbp2 != NULL; len += mbp2->m_len, mbp2 = mbp2->m_next);
 +  if (mbp->m_flags & M_PKTHDR)
 +    len = mbp->m_pkthdr.len;
 +  else {
 +    struct mbuf* mbp2 = mbp;
 +    for (len = 0; mbp2 != NULL; len += mbp2->m_len, mbp2 = mbp2->m_next);
 +  }
 +
 +#if XE_DEBUG > 2
 +  device_printf(scp->dev, "pio_write_packet: len = %u\n", len);
 +#endif
  
    /* Packets < minimum length may need to be padded out */
    pad = 0;
 -  if (len < ETHER_MIN_LEN - ETHER_CRC_LEN) {
 -    pad = (ETHER_MIN_LEN - ETHER_CRC_LEN - len + 1) >> 1;
 -    len = ETHER_MIN_LEN - ETHER_CRC_LEN;
 +  if (len < scp->tx_min) {
 +    pad = scp->tx_min - len;
 +    len = scp->tx_min;
    }
  
    /* Check transmit buffer space */
    XE_SELECT_PAGE(0);
 -  XE_OUTW(XE_TRS, len+2);
 -  free = XE_INW(XE_TSO);
 -  ok = free & 0x8000;
 -  free &= 0x7fff;
 -  if (free <= len + 2)
 +  XE_OUTW(XE_TRS, len+2);	/* Only effective on rev. 1 CE2 cards */
 +  if ((XE_INW(XE_TSO) & 0x7fff) <= len + 2)
      return 1;
  
    /* Send packet length to card */
 @@ -1544,7 +1551,7 @@
        }
        if (len > 1) {		/* Output contiguous words */
  	bus_space_write_multi_2(scp->bst, scp->bsh, XE_EDP, (u_int16_t *) data,
 -	 len >> 1);
 +				len >> 1);
  	data += len & ~1;
  	len &= 1;
        }
 @@ -1555,21 +1562,30 @@
      }
      mbp = mbp->m_next;
    }
 -  if (wantbyte)			/* Last byte for odd-length packets */
 -    XE_OUTW(XE_EDP, *(u_short *)savebyte);
  
    /*
 -   * For CE3 cards, just tell 'em to send -- apparently the card will pad out
 -   * short packets with random cruft.  Otherwise, write nonsense words to fill 
 -   * out the packet.  I guess it is then sent automatically (?)
 +   * Send last byte of odd-length packets
 +   */
 +  if (wantbyte)
 +    XE_OUTB(XE_EDP, savebyte[0]);
 +
 +  /*
 +   * Can just tell CE3 cards to send; short packets will be padded out with
 +   * random cruft automatically.  For CE2, manually pad the packet with
 +   * garbage; it will be sent when the required number or bytes have been
 +   * delivered to the card.
     */
    if (scp->mohawk)
      XE_OUTB(XE_CR, XE_CR_TX_PACKET | XE_CR_RESTART_TX | XE_CR_ENABLE_INTR);
 -  else
 +  else if (pad > 0) {
 +    if (pad & 0x01)
 +      XE_OUTB(XE_EDP, 0xaa);
 +    pad >>= 1;
      while (pad > 0) {
        XE_OUTW(XE_EDP, 0xdead);
        pad--;
      }
 +  }
  
    return 0;
  }
 Index: sys/dev/xe/if_xe_pccard.c
 ===================================================================
 RCS file: /home/ncvs/src/sys/dev/xe/if_xe_pccard.c,v
 retrieving revision 1.7.10000.1
 diff -u -r1.7.10000.1 if_xe_pccard.c
 --- sys/dev/xe/if_xe_pccard.c	25 Mar 2003 21:02:31 -0000	1.7.10000.1
 +++ sys/dev/xe/if_xe_pccard.c	23 Apr 2003 15:17:58 -0000
 @@ -58,7 +58,7 @@
   * Set XE_DEBUG to enable debug messages
   * Larger values increase verbosity
   */
 -#define XE_DEBUG 2
 +#define XE_DEBUG 0
  
  #define XE_VENDOR_ID_XIRCOM 0x0105
  #define XE_VENDOR_ID_COMPAQ_1 0x0138
 @@ -81,18 +81,19 @@
  #define XE_CARD_TYPE_FLAGS_CE2 0x1
  #define XE_CARD_TYPE_FLAGS_MOHAWK 0x2
  #define XE_CARD_TYPE_FLAGS_DINGO 0x4
 -#define XE_PROD_UMASK 0x100f
 -#define XE_PROD_MODEM_UMASK 0x1000
 -#define XE_PROD_SINGLE_ID1 0x1
 -#define XE_PROD_SINGLE_ID2 0x2
 -#define XE_PROD_SINGLE_ID3 0x3
 -#define XE_PROD_MULTI_ID1 0x1001
 -#define XE_PROD_MULTI_ID2 0x1002
 -#define XE_PROD_MULTI_ID3 0x1003
 -#define XE_PROD_MULTI_ID4 0x1004
 -#define XE_PROD_MULTI_ID5 0x1005
 -#define XE_PROD_MULTI_ID6 0x1006 
 -#define XE_PROD_MULTI_ID7 0x1007  
 +#define XE_PROD_UMASK 0x11000f
 +#define XE_PROD_ETHER_UMASK 0x010000
 +#define XE_PROD_MODEM_UMASK 0x100000
 +#define XE_PROD_SINGLE_ID1 0x010001
 +#define XE_PROD_SINGLE_ID2 0x010002
 +#define XE_PROD_SINGLE_ID3 0x010003
 +#define XE_PROD_MULTI_ID1 0x110001
 +#define XE_PROD_MULTI_ID2 0x110002
 +#define XE_PROD_MULTI_ID3 0x110003
 +#define XE_PROD_MULTI_ID4 0x110004
 +#define XE_PROD_MULTI_ID5 0x110005
 +#define XE_PROD_MULTI_ID6 0x110006 
 +#define XE_PROD_MULTI_ID7 0x110007  
  
  struct xe_card_type_table {
  	u_int32_t prod_type;
 @@ -137,7 +138,7 @@
  	int rid;
  	int ioport;
  
 -#ifdef XE_DEBUG
 +#if XE_DEBUG > 1
  	device_printf(dev, "cem56fix\n");
  #endif
  
 @@ -218,8 +219,25 @@
  	struct xe_card_type_table *card_itm;
  	int i;
  
 -#ifdef XE_DEBUG
 +#if XE_DEBUG > 1
 +	char* vendor_str = NULL;
 +	char* product_str = NULL;
 +	char* cis4_str = NULL;
  	device_printf(dev, "pccard_probe\n");
 +	pccard_get_vendor(dev, &vendor);
 +	pccard_get_product(dev, &prodid);
 +	pccard_get_prodext(dev, &prodext);
 +	pccard_get_vendor_str(dev, &vendor_str);
 +	pccard_get_product_str(dev, &product_str);
 +	pccard_get_cis3_str(dev, &cis3_str);
 +	pccard_get_cis4_str(dev, &cis4_str);
 +	device_printf(dev, "vendor = 0x%04x\n", vendor);
 +	device_printf(dev, "product = 0x%04x\n", prodid);
 +	device_printf(dev, "prodext = 0x%02x\n", prodext);
 +	device_printf(dev, "vendor_str = %s\n", vendor_str);
 +	device_printf(dev, "product_str = %s\n", product_str);
 +	device_printf(dev, "cis3_str = %s\n", cis3_str);
 +	device_printf(dev, "cis4_str = %s\n", cis4_str);
  #endif
  
  	/*
 @@ -258,7 +276,7 @@
  	 */
  	pccard_get_cis3_str(dev, &cis3_str);
  	if (strcmp(scp->card_type, "CE") == 0)
 -		if (strcmp(cis3_str, "CE2") ==0)
 +		if (cis3_str != NULL && strcmp(cis3_str, "PS-CE2-10") == 0)
  			scp->card_type = "CE2"; /* Look for "CE2" string */
  
  	/*
 @@ -287,7 +305,7 @@
  	struct xe_softc *scp = device_get_softc(dev);
  	int err;
  
 -#ifdef XE_DEBUG
 +#if XE_DEBUG > 1
  	device_printf(dev, "pccard_attach\n");
  #endif
  
 @@ -318,7 +336,7 @@
  {
  	struct xe_softc *sc = device_get_softc(dev);
  
 -#ifdef XE_DEBUG
 +#if XE_DEBUG > 1
  	device_printf(dev, "pccard_detach\n");
  #endif
  
 @@ -348,7 +366,7 @@
  {
  	const struct pccard_product *pp;
  
 -#ifdef XE_DEBUG
 +#if XE_DEBUG > 1
  	device_printf(dev, "pccard_match\n");
  #endif
  
 Index: sys/dev/xe/if_xevar.h
 ===================================================================
 RCS file: /home/ncvs/src/sys/dev/xe/if_xevar.h,v
 retrieving revision 1.3.10000.1
 diff -u -r1.3.10000.1 if_xevar.h
 --- sys/dev/xe/if_xevar.h	6 Apr 2003 12:12:52 -0000	1.3.10000.1
 +++ sys/dev/xe/if_xevar.h	13 Apr 2003 15:28:34 -0000
 @@ -53,6 +53,7 @@
    int tx_queued;	/* Packets currently waiting to transmit */
    int tx_tpr;		/* Last value of TPR reg on card */
    int tx_timeouts;	/* Count of transmit timeouts */
 +  u_int16_t tx_min;	/* Smallest packet we can send without padding */
    u_int16_t tx_thres;	/* Threshold bytes for early transmit */
    int autoneg_status;	/* Autonegotiation progress state */
    int media;		/* Private media word */


More information about the freebsd-bugs mailing list