diff options
Diffstat (limited to 'drivers/net/wireless/p54/main.c')
| -rw-r--r-- | drivers/net/wireless/p54/main.c | 31 | 
1 files changed, 31 insertions, 0 deletions
diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c index a946991989c..a5a6d9e647b 100644 --- a/drivers/net/wireless/p54/main.c +++ b/drivers/net/wireless/p54/main.c @@ -308,6 +308,31 @@ out:  	return ret;  } +static u64 p54_prepare_multicast(struct ieee80211_hw *dev, +				 struct netdev_hw_addr_list *mc_list) +{ +	struct p54_common *priv = dev->priv; +	struct netdev_hw_addr *ha; +	int i; + +	BUILD_BUG_ON(ARRAY_SIZE(priv->mc_maclist) != +		ARRAY_SIZE(((struct p54_group_address_table *)NULL)->mac_list)); +	/* +	 * The first entry is reserved for the global broadcast MAC. +	 * Otherwise the firmware will drop it and ARP will no longer work. +	 */ +	i = 1; +	priv->mc_maclist_num = netdev_hw_addr_list_count(mc_list) + i; +	netdev_hw_addr_list_for_each(ha, mc_list) { +		memcpy(&priv->mc_maclist[i], ha->addr, ETH_ALEN); +		i++; +		if (i >= ARRAY_SIZE(priv->mc_maclist)) +			break; +	} + +	return 1; /* update */ +} +  static void p54_configure_filter(struct ieee80211_hw *dev,  				 unsigned int changed_flags,  				 unsigned int *total_flags, @@ -316,12 +341,16 @@ static void p54_configure_filter(struct ieee80211_hw *dev,  	struct p54_common *priv = dev->priv;  	*total_flags &= FIF_PROMISC_IN_BSS | +			FIF_ALLMULTI |  			FIF_OTHER_BSS;  	priv->filter_flags = *total_flags;  	if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS))  		p54_setup_mac(priv); + +	if (changed_flags & FIF_ALLMULTI || multicast) +		p54_set_groupfilter(priv);  }  static int p54_conf_tx(struct ieee80211_hw *dev, u16 queue, @@ -591,6 +620,7 @@ static const struct ieee80211_ops p54_ops = {  	.config			= p54_config,  	.flush			= p54_flush,  	.bss_info_changed	= p54_bss_info_changed, +	.prepare_multicast	= p54_prepare_multicast,  	.configure_filter	= p54_configure_filter,  	.conf_tx		= p54_conf_tx,  	.get_stats		= p54_get_stats, @@ -660,6 +690,7 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)  	init_completion(&priv->beacon_comp);  	INIT_DELAYED_WORK(&priv->work, p54_work); +	memset(&priv->mc_maclist[0], ~0, ETH_ALEN);  	return dev;  }  EXPORT_SYMBOL_GPL(p54_init_common);  |