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 a946991989c6..a5a6d9e647bb 100644 --- a/drivers/net/wireless/p54/main.c +++ b/drivers/net/wireless/p54/main.c | |||
@@ -308,6 +308,31 @@ out: | |||
308 | return ret; | 308 | return ret; |
309 | } | 309 | } |
310 | 310 | ||
311 | static u64 p54_prepare_multicast(struct ieee80211_hw *dev, | ||
312 | struct netdev_hw_addr_list *mc_list) | ||
313 | { | ||
314 | struct p54_common *priv = dev->priv; | ||
315 | struct netdev_hw_addr *ha; | ||
316 | int i; | ||
317 | |||
318 | BUILD_BUG_ON(ARRAY_SIZE(priv->mc_maclist) != | ||
319 | ARRAY_SIZE(((struct p54_group_address_table *)NULL)->mac_list)); | ||
320 | /* | ||
321 | * The first entry is reserved for the global broadcast MAC. | ||
322 | * Otherwise the firmware will drop it and ARP will no longer work. | ||
323 | */ | ||
324 | i = 1; | ||
325 | priv->mc_maclist_num = netdev_hw_addr_list_count(mc_list) + i; | ||
326 | netdev_hw_addr_list_for_each(ha, mc_list) { | ||
327 | memcpy(&priv->mc_maclist[i], ha->addr, ETH_ALEN); | ||
328 | i++; | ||
329 | if (i >= ARRAY_SIZE(priv->mc_maclist)) | ||
330 | break; | ||
331 | } | ||
332 | |||
333 | return 1; /* update */ | ||
334 | } | ||
335 | |||
311 | static void p54_configure_filter(struct ieee80211_hw *dev, | 336 | static void p54_configure_filter(struct ieee80211_hw *dev, |
312 | unsigned int changed_flags, | 337 | unsigned int changed_flags, |
313 | unsigned int *total_flags, | 338 | unsigned int *total_flags, |
@@ -316,12 +341,16 @@ static void p54_configure_filter(struct ieee80211_hw *dev, | |||
316 | struct p54_common *priv = dev->priv; | 341 | struct p54_common *priv = dev->priv; |
317 | 342 | ||
318 | *total_flags &= FIF_PROMISC_IN_BSS | | 343 | *total_flags &= FIF_PROMISC_IN_BSS | |
344 | FIF_ALLMULTI | | ||
319 | FIF_OTHER_BSS; | 345 | FIF_OTHER_BSS; |
320 | 346 | ||
321 | priv->filter_flags = *total_flags; | 347 | priv->filter_flags = *total_flags; |
322 | 348 | ||
323 | if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) | 349 | if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) |
324 | p54_setup_mac(priv); | 350 | p54_setup_mac(priv); |
351 | |||
352 | if (changed_flags & FIF_ALLMULTI || multicast) | ||
353 | p54_set_groupfilter(priv); | ||
325 | } | 354 | } |
326 | 355 | ||
327 | static int p54_conf_tx(struct ieee80211_hw *dev, u16 queue, | 356 | static int p54_conf_tx(struct ieee80211_hw *dev, u16 queue, |
@@ -591,6 +620,7 @@ static const struct ieee80211_ops p54_ops = { | |||
591 | .config = p54_config, | 620 | .config = p54_config, |
592 | .flush = p54_flush, | 621 | .flush = p54_flush, |
593 | .bss_info_changed = p54_bss_info_changed, | 622 | .bss_info_changed = p54_bss_info_changed, |
623 | .prepare_multicast = p54_prepare_multicast, | ||
594 | .configure_filter = p54_configure_filter, | 624 | .configure_filter = p54_configure_filter, |
595 | .conf_tx = p54_conf_tx, | 625 | .conf_tx = p54_conf_tx, |
596 | .get_stats = p54_get_stats, | 626 | .get_stats = p54_get_stats, |
@@ -660,6 +690,7 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len) | |||
660 | init_completion(&priv->beacon_comp); | 690 | init_completion(&priv->beacon_comp); |
661 | INIT_DELAYED_WORK(&priv->work, p54_work); | 691 | INIT_DELAYED_WORK(&priv->work, p54_work); |
662 | 692 | ||
693 | memset(&priv->mc_maclist[0], ~0, ETH_ALEN); | ||
663 | return dev; | 694 | return dev; |
664 | } | 695 | } |
665 | EXPORT_SYMBOL_GPL(p54_init_common); | 696 | EXPORT_SYMBOL_GPL(p54_init_common); |