From: Prasanna Meda It is using local variable `i' in both the inner and outer loop. Need to bring the for loop outside the loop. Otherwise we need to reset the setup_frame to tp->setup_frame after every loop. You do not need to set the setup_frm for every mc address, we can set once after the complete has_table is ready. And also the 2.4 code missed a bit in tx_flags. 25-akpm/drivers/net/tulip/tulip_core.c | 13 +++++++------ 1 files changed, 7 insertions(+), 6 deletions(-) diff -puN drivers/net/tulip/tulip_core.c~tulip-hash-fix drivers/net/tulip/tulip_core.c --- 25/drivers/net/tulip/tulip_core.c~tulip-hash-fix Wed Nov 12 12:38:20 2003 +++ 25-akpm/drivers/net/tulip/tulip_core.c Wed Nov 12 12:40:02 2003 @@ -982,12 +982,12 @@ static void build_setup_frame_hash(u16 * set_bit_le(index, hash_table); - for (i = 0; i < 32; i++) { - *setup_frm++ = hash_table[i]; - *setup_frm++ = hash_table[i]; - } - setup_frm = &tp->setup_frame[13*6]; } + for (i = 0; i < 32; i++) { + *setup_frm++ = hash_table[i]; + *setup_frm++ = hash_table[i]; + } + setup_frm = &tp->setup_frame[13*6]; /* Fill the final entry with our physical address. */ eaddrs = (u16 *)dev->dev_addr; @@ -1087,11 +1087,13 @@ static void set_rx_mode(struct net_devic } } else { unsigned long flags; + u32 tx_flags = 0x08000000 | 192; /* Note that only the low-address shortword of setup_frame is valid! The values are doubled for big-endian architectures. */ if (dev->mc_count > 14) { /* Must use a multicast hash table. */ build_setup_frame_hash(tp->setup_frame, dev); + tx_flags = 0x08400000 | 192; } else { build_setup_frame_perfect(tp->setup_frame, dev); } @@ -1101,7 +1103,6 @@ static void set_rx_mode(struct net_devic if (tp->cur_tx - tp->dirty_tx > TX_RING_SIZE - 2) { /* Same setup recently queued, we need not add it. */ } else { - u32 tx_flags = 0x08000000 | 192; unsigned int entry; int dummy = -1; _