From d9a8a0a3574525bf422fd2f05eec739c0d25814f Mon Sep 17 00:00:00 2001 From: Komuro Date: Sat, 6 Aug 2005 12:01:43 +0900 Subject: [PATCH] [PATCH] network: fix fmvj18x_cs multicast code The multicast code of the fmvj18x_cs driver is broken. I fixed it to work properly. Signed-off-by: komurojun-mbn@nifty.com Signed-off-by: Jeff Garzik --- drivers/net/pcmcia/fmvj18x_cs.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c index 9d8197bb293a..384a736a0d2f 100644 --- a/drivers/net/pcmcia/fmvj18x_cs.c +++ b/drivers/net/pcmcia/fmvj18x_cs.c @@ -134,7 +134,7 @@ typedef struct local_info_t { u_char mc_filter[8]; } local_info_t; -#define MC_FILTERBREAK 64 +#define MC_FILTERBREAK 8 /*====================================================================*/ /* @@ -1012,7 +1012,7 @@ static void fjn_reset(struct net_device *dev) outb(BANK_1U, ioaddr + CONFIG_1); /* set the multicast table to accept none. */ - for (i = 0; i < 6; i++) + for (i = 0; i < 8; i++) outb(0x00, ioaddr + MAR_ADR + i); /* Switch to bank 2 (runtime mode) */ @@ -1269,6 +1269,16 @@ static void set_rx_mode(struct net_device *dev) u_long flags; int i; + int saved_config_0 = inb(ioaddr + CONFIG_0); + + local_irq_save(flags); + + /* Disable Tx and Rx */ + if (sram_config == 0) + outb(CONFIG0_RST, ioaddr + CONFIG_0); + else + outb(CONFIG0_RST_1, ioaddr + CONFIG_0); + if (dev->flags & IFF_PROMISC) { /* Unconditionally log net taps. */ printk("%s: Promiscuous mode enabled.\n", dev->name); @@ -1290,20 +1300,23 @@ static void set_rx_mode(struct net_device *dev) for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; i++, mclist = mclist->next) { unsigned int bit = - ether_crc_le(ETH_ALEN, mclist->dmi_addr) & 0x3f; - mc_filter[bit >> 3] |= (1 << bit); + ether_crc_le(ETH_ALEN, mclist->dmi_addr) >> 26; + mc_filter[bit >> 3] |= (1 << (bit & 7)); } + outb(2, ioaddr + RX_MODE); /* Use normal mode. */ } - local_irq_save(flags); if (memcmp(mc_filter, lp->mc_filter, sizeof(mc_filter))) { int saved_bank = inb(ioaddr + CONFIG_1); /* Switch to bank 1 and set the multicast table. */ outb(0xe4, ioaddr + CONFIG_1); for (i = 0; i < 8; i++) - outb(mc_filter[i], ioaddr + 8 + i); + outb(mc_filter[i], ioaddr + MAR_ADR + i); memcpy(lp->mc_filter, mc_filter, sizeof(mc_filter)); outb(saved_bank, ioaddr + CONFIG_1); } + + outb(saved_config_0, ioaddr + CONFIG_0); + local_irq_restore(flags); }