aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/p54/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/p54/main.c')
-rw-r--r--drivers/net/wireless/p54/main.c31
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
311static 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
311static void p54_configure_filter(struct ieee80211_hw *dev, 336static 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
327static int p54_conf_tx(struct ieee80211_hw *dev, u16 queue, 356static 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}
665EXPORT_SYMBOL_GPL(p54_init_common); 696EXPORT_SYMBOL_GPL(p54_init_common);