[1437] in linux-net channel archive

home help back first fref pref prev next nref lref last post

Re: de4x5.c fails compile in 1.3.44

daemon@ATHENA.MIT.EDU (davies@wanton.lkg.dec.com)
Tue Nov 28 01:38:10 1995

From: davies@wanton.lkg.dec.com
To: baba@beckman.uiuc.edu, linux-kernel@vger.rutgers.edu,
        linux-net@vger.rutgers.edu
Cc: davies@wanton.lkg.dec.com
In-Reply-To: Your message of "Sun, 26 Nov 95 13:39:07 CST."
             <199511261939.NAA03001@tigger.beckman.uiuc.edu> 
Date: Mon, 27 Nov 95 14:32:49 -0500

Baba,

> I haven't tried to fix this yet... someone else can probably do it faster than

Hmm and I couldn't believe the mess someone else made. Here's
replacements for the set_multicast_list() and SetMulticastFilter() functions.

You will need to hand edit all references to set_multicast_list()
elsewhere in the driver (they're in the ioctl section which few people
use: delete unecessary parameters).

Regards,

Dave

----------------------------

/*
** Set or clear the multicast filter for this adaptor.
*/
static void
set_multicast_list(struct device *dev)
{
  struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
  u_long iobase = dev->base_addr;

  /* First, double check that the adapter is open */
  if (irq2dev_map[dev->irq] != NULL) {
    if (dev->flags & IFF_PROMISC) {         /* set promiscuous mode */
      u32 omr;
      omr = inl(DE4X5_OMR);
      omr |= OMR_PR;
      outl(omr, DE4X5_OMR);
    } else { 
      SetMulticastFilter(dev);
      if (lp->setup_f == HASH_PERF) {
	load_packet(dev, lp->setup_frame, TD_IC | HASH_F | TD_SET | 
		                                        SETUP_FRAME_LEN, NULL);
      } else {
	load_packet(dev, lp->setup_frame, TD_IC | PERFECT_F | TD_SET | 
		                                        SETUP_FRAME_LEN, NULL);
      }
      
      lp->tx_new = (++lp->tx_new) % lp->txRingSize;
      outl(POLL_DEMAND, DE4X5_TPD);                /* Start the TX */
      dev->trans_start = jiffies;
    }
  }

  return;
}

/*
** Calculate the hash code and update the logical address filter
** from a list of ethernet multicast addresses.
** Little endian crc one liner from Matt Thomas, DEC.
*/
static void SetMulticastFilter(struct device *dev)
{
  struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
  struct dev_mc_list *dmi=dev->mc_list;
  u_long iobase = dev->base_addr;
  int i, j, bit, byte;
  u16 hashcode;
  u32 omr, crc, poly = CRC_POLYNOMIAL_LE;
  char *pa;
  unsigned char *addrs;

  omr = inl(DE4X5_OMR);
  omr &= ~OMR_PR;
  pa = build_setup_frame(dev, ALL);          /* Build the basic frame */

  if ((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 14)) {
    omr |= OMR_PM;                           /* Pass all multicasts */
  } else if (lp->setup_f == HASH_PERF) {
                                             /* Now update the MCA table */
    for (i=0;i<dev->mc_count;i++) {          /* for each address in the list */
      addrs=dmi->dmi_addr;
      dmi=dmi->next;
      if ((*addrs & 0x01) == 1) {            /* multicast address? */ 
	crc = 0xffffffff;                    /* init CRC for each address */
	for (byte=0;byte<ETH_ALEN;byte++) {  /* for each address byte */
	                                     /* process each address bit */ 
	  for (bit = *addrs++,j=0;j<8;j++, bit>>=1) {
	    crc = (crc >> 1) ^ (((crc ^ bit) & 0x01) ? poly : 0);
	  }
	}
	hashcode = crc & HASH_BITS;          /* hashcode is 9 LSb of CRC */
	
	byte = hashcode >> 3;                /* bit[3-8] -> byte in filter */
	bit = 1 << (hashcode & 0x07);        /* bit[0-2] -> bit in byte */
	
	byte <<= 1;                          /* calc offset into setup frame */
	if (byte & 0x02) {
	  byte -= 1;
	}
	lp->setup_frame[byte] |= bit;
      }
    }
  } else {                                   /* Perfect filtering */
    for (j=0; j<dev->mc_count; j++) {
      addrs=dmi->dmi_addr;
      dmi=dmi->next;
      for (i=0; i<ETH_ALEN; i++) { 
	*(pa + (i&1)) = *addrs++;
	if (i & 0x01) pa += 4;
      }
    }
  }
  outl(omr, DE4X5_OMR);

  return;
}

home help back first fref pref prev next nref lref last post