kernels/linux-2.4.0/drivers/net/3c527.c
/**
 *	do_mc32_set_multicast_list:
 *	@dev: 3c527 device to load the list on
 *	@retry: indicates this is not the first call. 
 *
 * Actually set or clear the multicast filter for this adaptor. The locking
 * issues are handled by this routine. We have to track state as it may take
 * multiple calls to get the command sequence completed. We just keep trying
 * to schedule the loads until we manage to process them all.
 *
 * num_addrs == -1	Promiscuous mode, receive all packets
 *
 * num_addrs == 0	Normal mode, clear multicast list
 *
 * num_addrs > 0	Multicast mode, receive normal and MC packets,
 *			and do best-effort filtering.
 */
@dev: 3c527 device to load the list on
@retry: indicates this is not the first call.

Actually set or clear the multicast filter for this adaptor. The locking
issues are handled by this routine. We have to track state as it may take
multiple calls to get the command sequence completed. We just keep trying
to schedule the loads until we manage to process them all.

num_addrs == -1      Promiscuous mode, receive all packets

num_addrs == 0       Normal mode, clear multicast list

num_addrs > 0        Multicast mode, receive normal and MC packets,
and do best-effort filtering.
@dev : 3c527 device to load the list on @retry : indicates this is not the first call . Actually set or clear the multicast filter for this adaptor . The locking issues are handled by this routine . We have to track state as it may take multiple calls to get the command sequence completed . We just keep trying to schedule the loads until we manage to process them all . num_addrs == - 1 Promiscuous mode receive all packets num_addrs == 0 Normal mode clear multicast list num_addrs > 0 Multicast mode receive normal and MC packets and do best - effort filtering .
static void do_mc32_set_multicast_list(struct net_device *dev, int retry)
{
	struct mc32_local *lp = (struct mc32_local *)dev->priv;
	u16 filt;
	if (dev->flags&IFF_PROMISC)
		filt = 1;
	else if((dev->flags&IFF_ALLMULTI) || dev->mc_count > 10)
	{
		dev->flags|=IFF_PROMISC;
		filt = 1;
	}
	else if(dev->mc_count)
	{
		unsigned char block[62];
		unsigned char *bp;
		struct dev_mc_list *dmc=dev->mc_list;
		int i;
		filt = 0;
		if(retry==0)
			lp->mc_list_valid = 0;
		if(!lp->mc_list_valid)
		{
			block[1]=0;
			block[0]=dev->mc_count;
			bp=block+2;
			for(i=0;i<dev->mc_count;i++)
			{
				memcpy(bp, dmc->dmi_addr, 6);
				bp+=6;
				dmc=dmc->next;
			}
			if(mc32_command_nowait(dev, 2, block, 2+6*dev->mc_count)==-1)
			{
				lp->mc_reload_wait = 1;
				return;
			}
			lp->mc_list_valid=1;
		}
	}
	else 
	{
		filt = 0;
	}
	if(mc32_command_nowait(dev, 0, &filt, 2)==-1)
	{
		lp->mc_reload_wait = 1;
	}
}
static void do_mc32_set_multicast_list ( struct net_device * dev , int retry ) { struct mc32_local * lp = ( struct mc32_local * ) dev -> priv ; u16 filt ; if ( dev -> flags & IFF_PROMISC ) filt = 1 ; else if ( ( dev -> flags & IFF_ALLMULTI ) || dev -> mc_count > 10 ) { dev -> flags |= IFF_PROMISC ; filt = 1 ; } else if ( dev -> mc_count ) { unsigned char block [ 62 ] ; unsigned char * bp ; struct dev_mc_list * dmc = dev -> mc_list ; int i ; filt = 0 ; if ( retry == 0 ) lp -> mc_list_valid = 0 ; if ( ! lp -> mc_list_valid ) { block [ 1 ] = 0 ; block [ 0 ] = dev -> mc_count ; bp = block + 2 ; for ( i = 0 ; i < dev -> mc_count ; i ++ ) { memcpy ( bp , dmc -> dmi_addr , 6 ) ; bp += 6 ; dmc = dmc -> next ; } if ( mc32_command_nowait ( dev , 2 , block , 2 + 6 * dev -> mc_count ) == -1 ) { lp -> mc_reload_wait = 1 ; return ; } lp -> mc_list_valid = 1 ; } } else { filt = 0 ; } if ( mc32_command_nowait ( dev , 0 , & filt , 2 ) == -1 ) { lp -> mc_reload_wait = 1 ; } }
do_mc32_set_multicast_list:
      @dev: 3c527 device to load the list on
      @retry: indicates this is not the first call.
do_mc32_set_multicast_list : @dev : 3c527 device to load the list on @retry : indicates this is not the first call .
/* Enable promiscuous mode */