Пример #1
0
static void
set_multicast (struct net_device *dev)
{
	long ioaddr = dev->base_addr;
	u32 hash_table[2];
	u16 rx_mode = 0;
	struct netdev_private *np = netdev_priv(dev);

	hash_table[0] = hash_table[1] = 0;
	/*                                                      */
	hash_table[1] |= 0x02000000;
	if (dev->flags & IFF_PROMISC) {
		/*                                   */
		rx_mode = ReceiveAllFrames;
	} else if ((dev->flags & IFF_ALLMULTI) ||
			(netdev_mc_count(dev) > multicast_filter_limit)) {
		/*                                        */
		rx_mode = ReceiveBroadcast | ReceiveMulticast | ReceiveUnicast;
	} else if (!netdev_mc_empty(dev)) {
		struct netdev_hw_addr *ha;
		/*                                                        
                  */
		rx_mode =
		    ReceiveBroadcast | ReceiveMulticastHash | ReceiveUnicast;
		netdev_for_each_mc_addr(ha, dev) {
			int bit, index = 0;
			int crc = ether_crc_le(ETH_ALEN, ha->addr);
			/*                                                
                                    */
			for (bit = 0; bit < 6; bit++)
				if (crc & (1 << (31 - bit)))
					index |= (1 << bit);
			hash_table[index / 32] |= (1 << (index % 32));
		}
	} else {
Пример #2
0
static void
set_multicast (struct net_device *dev)
{
	struct netdev_private *np = netdev_priv(dev);
	void __iomem *ioaddr = np->ioaddr;
	u32 hash_table[2];
	u16 rx_mode = 0;

	hash_table[0] = hash_table[1] = 0;
	/* RxFlowcontrol DA: 01-80-C2-00-00-01. Hash index=0x39 */
	hash_table[1] |= 0x02000000;
	if (dev->flags & IFF_PROMISC) {
		/* Receive all frames promiscuously. */
		rx_mode = ReceiveAllFrames;
	} else if ((dev->flags & IFF_ALLMULTI) ||
			(netdev_mc_count(dev) > multicast_filter_limit)) {
		/* Receive broadcast and multicast frames */
		rx_mode = ReceiveBroadcast | ReceiveMulticast | ReceiveUnicast;
	} else if (!netdev_mc_empty(dev)) {
		struct netdev_hw_addr *ha;
		/* Receive broadcast frames and multicast frames filtering
		   by Hashtable */
		rx_mode =
		    ReceiveBroadcast | ReceiveMulticastHash | ReceiveUnicast;
		netdev_for_each_mc_addr(ha, dev) {
			int bit, index = 0;
			int crc = ether_crc_le(ETH_ALEN, ha->addr);
			/* The inverted high significant 6 bits of CRC are
			   used as an index to hashtable */
			for (bit = 0; bit < 6; bit++)
				if (crc & (1 << (31 - bit)))
					index |= (1 << bit);
			hash_table[index / 32] |= (1 << (index % 32));
		}
	} else {
Пример #3
0
/*
 * Set or clear the multicast filter for this adaptor.
 */
static void korina_multicast_list(struct net_device *dev)
{
	struct korina_private *lp = netdev_priv(dev);
	unsigned long flags;
	struct netdev_hw_addr *ha;
	u32 recognise = ETH_ARC_AB;	/* always accept broadcasts */

	/* Set promiscuous mode */
	if (dev->flags & IFF_PROMISC)
		recognise |= ETH_ARC_PRO;

	else if ((dev->flags & IFF_ALLMULTI) || (netdev_mc_count(dev) > 4))
		/* All multicast and broadcast */
		recognise |= ETH_ARC_AM;

	/* Build the hash table */
	if (netdev_mc_count(dev) > 4) {
		u16 hash_table[4] = { 0 };
		u32 crc;

		netdev_for_each_mc_addr(ha, dev) {
			crc = ether_crc_le(6, ha->addr);
			crc >>= 26;
			hash_table[crc >> 4] |= 1 << (15 - (crc & 0xf));
		}
Пример #4
0
/*
 *  Set DM9000 multicast address
 */
static void
dm9000_hash_table_unlocked(struct net_device *dev)
{
	board_info_t *db = netdev_priv(dev);
	struct netdev_hw_addr *ha;
	int i, oft;
	u32 hash_val;
	u16 hash_table[4];
	u8 rcr = RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN;

	//dm9000_dbg(db, 1, "entering %s\n", __func__);

	for (i = 0, oft = DM9000_PAR; i < 6; i++, oft++)
		iow(db, oft, dev->dev_addr[i]);

	/* Clear Hash Table */
	for (i = 0; i < 4; i++)
		hash_table[i] = 0x0;

	/* broadcast address */
	hash_table[3] = 0x8000;

	if (dev->flags & IFF_PROMISC)
		rcr |= RCR_PRMSC;

	if (dev->flags & IFF_ALLMULTI)
		rcr |= RCR_ALL;

	/* the multicast address in Hash Table : 64 bits */
	netdev_for_each_mc_addr(ha, dev) {
		hash_val = ether_crc_le(6, ha->addr) & 0x3f;
		hash_table[hash_val / 16] |= (u16) 1 << (hash_val % 16);
	}
Пример #5
0
/*
  Calculate the CRC valude of the Rx packet
  flag = 1 : return the reverse CRC (for the received packet CRC)
         0 : return the normal CRC (for Hash Table index)
*/
static unsigned long cal_CRC(unsigned char * Data, unsigned int Len, u8 flag)
{	
	u32 crc = ether_crc_le(Len, Data);

	if (flag) 
		return ~crc;
		
	return crc;	 
}
Пример #6
0
static void mace_set_multicast(struct net_device *dev)
{
	struct mace_data *mp = netdev_priv(dev);
	volatile struct mace *mb = mp->mace;
	int i, j;
	u32 crc;
	u8 maccc;
	unsigned long flags;

	local_irq_save(flags);
	maccc = mb->maccc;
	mb->maccc &= ~PROM;

	if (dev->flags & IFF_PROMISC) {
		mb->maccc |= PROM;
	} else {
		unsigned char multicast_filter[8];
		struct dev_mc_list *dmi = dev->mc_list;

		if (dev->flags & IFF_ALLMULTI) {
			for (i = 0; i < 8; i++) {
				multicast_filter[i] = 0xFF;
			}
		} else {
			for (i = 0; i < 8; i++)
				multicast_filter[i] = 0;
			for (i = 0; i < dev->mc_count; i++) {
				crc = ether_crc_le(6, dmi->dmi_addr);
				j = crc >> 26;	/* bit number in multicast_filter */
				multicast_filter[j >> 3] |= 1 << (j & 7);
				dmi = dmi->next;
			}
		}

		if (mp->chipid == BROKEN_ADDRCHG_REV)
			mb->iac = LOGADDR;
		else {
			mb->iac = ADDRCHG | LOGADDR;
			while ((mb->iac & ADDRCHG) != 0)
				;
		}
		for (i = 0; i < 8; ++i)
			mb->ladrf = multicast_filter[i];
		if (mp->chipid != BROKEN_ADDRCHG_REV)
			mb->iac = 0;
	}

	mb->maccc = maccc;
	local_irq_restore(flags);
}
Пример #7
0
static void
set_multicast (struct net_device *dev)
{
	long ioaddr = dev->base_addr;
	u32 hash_table[2];
	u16 rx_mode = 0;
	struct netdev_private *np = netdev_priv(dev);

	hash_table[0] = hash_table[1] = 0;
	/* RxFlowcontrol DA: 01-80-C2-00-00-01. Hash index=0x39 */
	hash_table[1] |= 0x02000000;
	if (dev->flags & IFF_PROMISC) {
		/* Receive all frames promiscuously. */
		rx_mode = ReceiveAllFrames;
	} else if ((dev->flags & IFF_ALLMULTI) ||
			(dev->mc_count > multicast_filter_limit)) {
		/* Receive broadcast and multicast frames */
		rx_mode = ReceiveBroadcast | ReceiveMulticast | ReceiveUnicast;
	} else if (dev->mc_count > 0) {
		int i;
		struct dev_mc_list *mclist;
		/* Receive broadcast frames and multicast frames filtering
		   by Hashtable */
		rx_mode =
		    ReceiveBroadcast | ReceiveMulticastHash | ReceiveUnicast;
		for (i=0, mclist = dev->mc_list; mclist && i < dev->mc_count;
				i++, mclist=mclist->next)
		{
			int bit, index = 0;
			int crc = ether_crc_le (ETH_ALEN, mclist->dmi_addr);
			/* The inverted high significant 6 bits of CRC are
			   used as an index to hashtable */
			for (bit = 0; bit < 6; bit++)
				if (crc & (1 << (31 - bit)))
					index |= (1 << bit);
			hash_table[index / 32] |= (1 << (index % 32));
		}
	} else {
		rx_mode = ReceiveBroadcast | ReceiveUnicast;
	}
	if (np->vlan) {
		/* ReceiveVLANMatch field in ReceiveMode */
		rx_mode |= ReceiveVLANMatch;
	}

	writel (hash_table[0], ioaddr + HashTable0);
	writel (hash_table[1], ioaddr + HashTable1);
	writew (rx_mode, ioaddr + ReceiveMode);
}
Пример #8
0
static void qe_set_multicast(struct net_device *dev)
{
	struct sunqe *qep = netdev_priv(dev);
	struct netdev_hw_addr *ha;
	u8 new_mconfig = qep->mconfig;
	char *addrs;
	int i;
	u32 crc;

	/* Lock out others. */
	netif_stop_queue(dev);

	if ((dev->flags & IFF_ALLMULTI) || (netdev_mc_count(dev) > 64)) {
		sbus_writeb(MREGS_IACONFIG_ACHNGE | MREGS_IACONFIG_LARESET,
			    qep->mregs + MREGS_IACONFIG);
		while ((sbus_readb(qep->mregs + MREGS_IACONFIG) & MREGS_IACONFIG_ACHNGE) != 0)
			barrier();
		for (i = 0; i < 8; i++)
			sbus_writeb(0xff, qep->mregs + MREGS_FILTER);
		sbus_writeb(0, qep->mregs + MREGS_IACONFIG);
	} else if (dev->flags & IFF_PROMISC) {
		new_mconfig |= MREGS_MCONFIG_PROMISC;
	} else {
		u16 hash_table[4];
		u8 *hbytes = (unsigned char *) &hash_table[0];

		memset(hash_table, 0, sizeof(hash_table));
		netdev_for_each_mc_addr(ha, dev) {
			addrs = ha->addr;

			if (!(*addrs & 1))
				continue;
			crc = ether_crc_le(6, addrs);
			crc >>= 26;
			hash_table[crc >> 4] |= 1 << (crc & 0xf);
		}
		/* Program the qe with the new filter value. */
		sbus_writeb(MREGS_IACONFIG_ACHNGE | MREGS_IACONFIG_LARESET,
			    qep->mregs + MREGS_IACONFIG);
		while ((sbus_readb(qep->mregs + MREGS_IACONFIG) & MREGS_IACONFIG_ACHNGE) != 0)
			barrier();
		for (i = 0; i < 8; i++) {
			u8 tmp = *hbytes++;
			sbus_writeb(tmp, qep->mregs + MREGS_FILTER);
		}
		sbus_writeb(0, qep->mregs + MREGS_IACONFIG);
	}
Пример #9
0
static void mace_set_multicast(struct net_device *dev)
{
	struct mace_data *mp = netdev_priv(dev);
	volatile struct mace *mb = mp->mace;
	int i;
	u32 crc;
	u8 maccc;
	unsigned long flags;

	local_irq_save(flags);
	maccc = mb->maccc;
	mb->maccc &= ~PROM;

	if (dev->flags & IFF_PROMISC) {
		mb->maccc |= PROM;
	} else {
		unsigned char multicast_filter[8];
		struct netdev_hw_addr *ha;

		if (dev->flags & IFF_ALLMULTI) {
			for (i = 0; i < 8; i++) {
				multicast_filter[i] = 0xFF;
			}
		} else {
			for (i = 0; i < 8; i++)
				multicast_filter[i] = 0;
			netdev_for_each_mc_addr(ha, dev) {
				crc = ether_crc_le(6, ha->addr);
				/* bit number in multicast_filter */
				i = crc >> 26;
				multicast_filter[i >> 3] |= 1 << (i & 7);
			}
		}

		if (mp->chipid == BROKEN_ADDRCHG_REV)
			mb->iac = LOGADDR;
		else {
			mb->iac = ADDRCHG | LOGADDR;
			while ((mb->iac & ADDRCHG) != 0)
				;
		}
		for (i = 0; i < 8; ++i)
			mb->ladrf = multicast_filter[i];
		if (mp->chipid != BROKEN_ADDRCHG_REV)
			mb->iac = 0;
	}
Пример #10
0
/*
 * Set or clear the multicast filter for this adaptor.
 */
static void korina_multicast_list(struct net_device *dev)
{
	struct korina_private *lp = netdev_priv(dev);
	unsigned long flags;
	struct dev_mc_list *dmi = dev->mc_list;
	u32 recognise = ETH_ARC_AB;	/* always accept broadcasts */
	int i;

	/* Set promiscuous mode */
	if (dev->flags & IFF_PROMISC)
		recognise |= ETH_ARC_PRO;

	else if ((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 4))
		/* All multicast and broadcast */
		recognise |= ETH_ARC_AM;

	/* Build the hash table */
	if (dev->mc_count > 4) {
		u16 hash_table[4];
		u32 crc;

		for (i = 0; i < 4; i++)
			hash_table[i] = 0;

		for (i = 0; i < dev->mc_count; i++) {
			char *addrs = dmi->dmi_addr;

			dmi = dmi->next;

			if (!(*addrs & 1))
				continue;

			crc = ether_crc_le(6, addrs);
			crc >>= 26;
			hash_table[crc >> 4] |= 1 << (15 - (crc & 0xf));
		}
		/* Accept filtered multicast */
		recognise |= ETH_ARC_AFM;

		/* Fill the MAC hash tables with their values */
		writel((u32)(hash_table[1] << 16 | hash_table[0]),
					&lp->eth_regs->ethhash0);
		writel((u32)(hash_table[3] << 16 | hash_table[2]),
					&lp->eth_regs->ethhash1);
	}
Пример #11
0
static void mace_set_multicast(struct net_device *dev)
{
	struct mace_data *mp = (struct mace_data *) dev->priv;
	volatile struct mace *mb = mp->mace;
	int i, j;
	u32 crc;
	u8 maccc;

	maccc = mb->maccc;
	mb->maccc &= ~PROM;

	if (dev->flags & IFF_PROMISC) {
		mb->maccc |= PROM;
	} else {
		unsigned char multicast_filter[8];
		struct dev_mc_list *dmi = dev->mc_list;

		if (dev->flags & IFF_ALLMULTI) {
			for (i = 0; i < 8; i++) {
				multicast_filter[i] = 0xFF;
			}
		} else {
			for (i = 0; i < 8; i++) {
				multicast_filter[i] = 0;
			}
			for (i = 0; i < dev->mc_count; i++) {
				crc = ether_crc_le(6, dmi->dmi_addr);
				j = crc >> 26;	/* bit number in multicast_filter */
				multicast_filter[j >> 3] |= 1 << (j & 7);
				dmi = dmi->next;
			}
		}

		mb->iac = ADDRCHG | LOGADDR;
		while (mb->iac & ADDRCHG);
		
		for (i = 0; i < 8; ++i) {
			mb->ladrf = multicast_filter[i];
		}
	}

	mb->maccc = maccc;
}