- 论坛徽章:
- 0
|
回复 4# wwxxxxll
1、首先请看我在dm9000_hash_table函数中加的打印信息(用红色字体标注)
static void dm9000_hash_table(struct net_device *dev)
{
board_info_t *db = (board_info_t *) dev->priv;
struct dev_mc_list *mcptr = dev->mc_list; /*得到多播MAC地址结构体*/
int mc_cnt = dev->mc_count; /*得到多播MAC地址的数目*/
printk("mc_cnt:%d\n",mc_cnt); /*打印出多播MAC地址的数目*/
u32 hash_val;
u16 i, oft, hash_table[4];
unsigned long flags;
printk("dm9000_hash_table()\n" ;
spin_lock_irqsave(&db->lock,flags); /*在获得自旋锁之前禁止中断,而先前的中断状态保存在flags中*/
for (i = 0, oft = 0x10; i < 6; i++, oft++) /*设置MAC地址*/
iow(db, oft, dev->dev_addr);
for (i = 0; i < 4; i++) /*初始化hash table为0*/
hash_table = 0x0;
/* broadcast address */
hash_table[3] = 0x8000;
/*从组播列表中取出组播地址放入hash_table数组中*/
for (i = 0; i < mc_cnt; i++, mcptr = mcptr->next) {
hash_val = cal_CRC((char *) mcptr->dmi_addr, 6, 0) & 0x3f;
hash_table[hash_val / 16] |= (u16) 1 << (hash_val % 16);
printk("hash_val:%d\n",hash_val);
}
for(i=0;i<4;i++)
printk("hash_table[%d]:%x\n",i,hash_table);
/*将组播地址写入组播地址寄存器中*/
for (i = 0, oft = 0x16; i < 4; i++) {
iow(db, oft++, hash_table & 0xff);
iow(db, oft++, (hash_table >> & 0xff);
}
spin_unlock_irqrestore(&db->lock,flags);
}
2、再看输出的结果(如下图所示)
通过上图可知,hash_val=62,则hash_val % 16=14,hash_val / 16=3,由于之前执令hash_table[3] = 0x8000,所以执行 hash_table[hash_val / 16] |= (u16) 1 << (hash_val % 16)这段代码后,hash_table[3] = 0xc000;而hash_table[0~2]=0没有任何的变化,所以hash_table中存储的值为 0000-0000-0000-c000(十六进制),即为多播MAC地址,其第1字节的最低位为0,但是多播MAC地址的第1字节最低位不是应该为1吗???
|
|