[1437] in linux-net channel archive
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;
}