patch-1.3.44 linux/drivers/net/de4x5.c
Next file: linux/drivers/net/de620.c
Previous file: linux/drivers/net/atp.c
Back to the patch index
Back to the overall index
- Lines: 207
- Date:
Fri Nov 24 16:39:53 1995
- Orig file:
v1.3.43/linux/drivers/net/de4x5.c
- Orig date:
Thu Nov 9 11:23:49 1995
diff -u --recursive --new-file v1.3.43/linux/drivers/net/de4x5.c linux/drivers/net/de4x5.c
@@ -399,7 +399,7 @@
static void de4x5_interrupt(int irq, struct pt_regs *regs);
static int de4x5_close(struct device *dev);
static struct enet_statistics *de4x5_get_stats(struct device *dev);
-static void set_multicast_list(struct device *dev, int num_addrs, void *addrs);
+static void set_multicast_list(struct device *dev);
static int de4x5_ioctl(struct device *dev, struct ifreq *rq, int cmd);
/*
@@ -1384,35 +1384,42 @@
** Set all multicast bits (pass all multicasts).
*/
static void
-set_multicast_list(struct device *dev, int num_addrs, void *addrs)
+set_multicast_list(struct device *dev)
{
- struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
- u_long iobase = dev->base_addr;
+ 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 (num_addrs >= 0) {
- SetMulticastFilter(dev, num_addrs, (char *)addrs);
- if (lp->setup_f == HASH_PERF) {
- load_packet(dev, lp->setup_frame, TD_IC | HASH_F | TD_SET |
+ /* First, double check that the adapter is open */
+ if (irq2dev_map[dev->irq] != NULL)
+ {
+ if (num_addrs >= 0)
+ {
+ 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 |
+ }
+ 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;
- } else { /* set promiscuous mode */
- u32 omr;
- omr = inl(DE4X5_OMR);
- omr |= OMR_PR;
- outl(omr, DE4X5_OMR);
- }
- }
+ }
- return;
+ lp->tx_new = (++lp->tx_new) % lp->txRingSize;
+ outl(POLL_DEMAND, DE4X5_TPD); /* Start the TX */
+ dev->trans_start = jiffies;
+ }
+ else
+ {
+ /* set promiscuous mode */
+ u32 omr;
+ omr = inl(DE4X5_OMR);
+ omr |= OMR_PR;
+ outl(omr, DE4X5_OMR);
+ }
+ }
+ return;
}
/*
@@ -1420,64 +1427,88 @@
** from a list of ethernet multicast addresses.
** Little endian crc one liner from Matt Thomas, DEC.
*/
-static void SetMulticastFilter(struct device *dev, int num_addrs, char *addrs)
+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);
pa = build_setup_frame(dev, ALL); /* Build the basic frame */
- if (lp->setup_f == HASH_PERF) {
- if (num_addrs == HASH_TABLE_LEN) { /* Pass all multicasts */
- omr |= OMR_PM;
- } else {
- omr &= ~OMR_PM;
+ if (lp->setup_f == HASH_PERF)
+ {
+ if (num_addrs >= HASH_TABLE_LEN || (dev->flags&IFF_ALLMULTI))
+ {
+ /* Pass all multicasts */
+ omr |= OMR_PM;
+ }
+ else
+ {
+ omr &= ~OMR_PM;
/* Now update the MCA table */
- for (i=0;i<num_addrs;i++) { /* for each address in the list */
- 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;
+ for (i=0;i<num_addrs;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 { /* skip this address */
- addrs += ETH_ALEN;
+ }
+ else
+ { /* skip this address */
+ addrs += ETH_ALEN;
+ }
+ }
+ }
+ else
+ { /* Perfect filtering */
+ omr &= ~OMR_PM;
+ 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;
+ }
+ }
}
- }
- }
- } else { /* Perfect filtering */
- omr &= ~OMR_PM;
- for (j=0; j<num_addrs; j++) {
- for (i=0; i<ETH_ALEN; i++) {
- *(pa + (i&1)) = *addrs++;
- if (i & 0x01) pa += 4;
- }
- }
- }
- if (num_addrs == 0)
- omr &= ~OMR_PR;
- outl(omr, DE4X5_OMR);
+ if (dev->mc_count == 0)
+ omr &= ~OMR_PR;
+ outl(omr, DE4X5_OMR);
- return;
+ return;
}
/*
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this