aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/mac80211.h7
-rw-r--r--net/mac80211/driver-ops.h16
-rw-r--r--net/mac80211/iface.c11
-rw-r--r--net/mac80211/trace.h24
4 files changed, 58 insertions, 0 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 8c0ca11a39c4..f5db5e970428 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -2259,6 +2259,9 @@ enum ieee80211_roc_type {
2259 * See the section "Frame filtering" for more information. 2259 * See the section "Frame filtering" for more information.
2260 * This callback must be implemented and can sleep. 2260 * This callback must be implemented and can sleep.
2261 * 2261 *
2262 * @set_multicast_list: Configure the device's interface specific RX multicast
2263 * filter. This callback is optional. This callback must be atomic.
2264 *
2262 * @set_tim: Set TIM bit. mac80211 calls this function when a TIM bit 2265 * @set_tim: Set TIM bit. mac80211 calls this function when a TIM bit
2263 * must be set or cleared for a given STA. Must be atomic. 2266 * must be set or cleared for a given STA. Must be atomic.
2264 * 2267 *
@@ -2605,6 +2608,10 @@ struct ieee80211_ops {
2605 unsigned int changed_flags, 2608 unsigned int changed_flags,
2606 unsigned int *total_flags, 2609 unsigned int *total_flags,
2607 u64 multicast); 2610 u64 multicast);
2611 void (*set_multicast_list)(struct ieee80211_hw *hw,
2612 struct ieee80211_vif *vif, bool allmulti,
2613 struct netdev_hw_addr_list *mc_list);
2614
2608 int (*set_tim)(struct ieee80211_hw *hw, struct ieee80211_sta *sta, 2615 int (*set_tim)(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
2609 bool set); 2616 bool set);
2610 int (*set_key)(struct ieee80211_hw *hw, enum set_key_cmd cmd, 2617 int (*set_key)(struct ieee80211_hw *hw, enum set_key_cmd cmd,
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 832acea4a5cb..025b7592b797 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -241,6 +241,22 @@ static inline u64 drv_prepare_multicast(struct ieee80211_local *local,
241 return ret; 241 return ret;
242} 242}
243 243
244static inline void drv_set_multicast_list(struct ieee80211_local *local,
245 struct ieee80211_sub_if_data *sdata,
246 struct netdev_hw_addr_list *mc_list)
247{
248 bool allmulti = sdata->flags & IEEE80211_SDATA_ALLMULTI;
249
250 trace_drv_set_multicast_list(local, sdata, mc_list->count);
251
252 check_sdata_in_driver(sdata);
253
254 if (local->ops->set_multicast_list)
255 local->ops->set_multicast_list(&local->hw, &sdata->vif,
256 allmulti, mc_list);
257 trace_drv_return_void(local);
258}
259
244static inline void drv_configure_filter(struct ieee80211_local *local, 260static inline void drv_configure_filter(struct ieee80211_local *local,
245 unsigned int changed_flags, 261 unsigned int changed_flags,
246 unsigned int *total_flags, 262 unsigned int *total_flags,
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index d85282f64405..9875e321c9e8 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -919,6 +919,17 @@ static void ieee80211_set_multicast_list(struct net_device *dev)
919 atomic_dec(&local->iff_promiscs); 919 atomic_dec(&local->iff_promiscs);
920 sdata->flags ^= IEEE80211_SDATA_PROMISC; 920 sdata->flags ^= IEEE80211_SDATA_PROMISC;
921 } 921 }
922
923 /*
924 * TODO: If somebody needs this on AP interfaces,
925 * it can be enabled easily but multicast
926 * addresses from VLANs need to be synced.
927 */
928 if (sdata->vif.type != NL80211_IFTYPE_MONITOR &&
929 sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
930 sdata->vif.type != NL80211_IFTYPE_AP)
931 drv_set_multicast_list(local, sdata, &dev->mc);
932
922 spin_lock_bh(&local->filter_lock); 933 spin_lock_bh(&local->filter_lock);
923 __hw_addr_sync(&local->mc_list, &dev->mc, dev->addr_len); 934 __hw_addr_sync(&local->mc_list, &dev->mc, dev->addr_len);
924 spin_unlock_bh(&local->filter_lock); 935 spin_unlock_bh(&local->filter_lock);
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index e7db2b804e0c..d97e4305cf1e 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -431,6 +431,30 @@ TRACE_EVENT(drv_prepare_multicast,
431 ) 431 )
432); 432);
433 433
434TRACE_EVENT(drv_set_multicast_list,
435 TP_PROTO(struct ieee80211_local *local,
436 struct ieee80211_sub_if_data *sdata, int mc_count),
437
438 TP_ARGS(local, sdata, mc_count),
439
440 TP_STRUCT__entry(
441 LOCAL_ENTRY
442 __field(bool, allmulti)
443 __field(int, mc_count)
444 ),
445
446 TP_fast_assign(
447 LOCAL_ASSIGN;
448 __entry->allmulti = sdata->flags & IEEE80211_SDATA_ALLMULTI;
449 __entry->mc_count = mc_count;
450 ),
451
452 TP_printk(
453 LOCAL_PR_FMT " configure mc filter, count=%d, allmulti=%d",
454 LOCAL_PR_ARG, __entry->mc_count, __entry->allmulti
455 )
456);
457
434TRACE_EVENT(drv_configure_filter, 458TRACE_EVENT(drv_configure_filter,
435 TP_PROTO(struct ieee80211_local *local, 459 TP_PROTO(struct ieee80211_local *local,
436 unsigned int changed_flags, 460 unsigned int changed_flags,