mirror of
https://github.com/torvalds/linux.git
synced 2024-12-19 17:41:29 +00:00
ath6kl: Multicast filter support in wow suspend and non-suspend
This patch enables all multicast packets in non suspend mode and enable multicast filtering in wow suspend mode. This also fixes a bug in multicast where the driver assumed disable multicast-all command disabled/filtered all multicast packets, which was wrong assumption, because firmware will apply the programmed filter. Multicast requirements - Enable forward all multicast packets(no filtering) in non suspend mode. - Enable multicast filtering in wow suspend mode for both AP and CLIENT. kvalo: fix a checkpatch warning and drop unrelated newline removal Signed-off-by: Naveen Gangadharan <ngangadh@qca.qualcomm.com> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
This commit is contained in:
parent
03e2084a84
commit
6251d8012d
@ -2076,6 +2076,13 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
|
||||
if (wow && (wow->n_patterns > WOW_MAX_FILTERS_PER_LIST))
|
||||
return -EINVAL;
|
||||
|
||||
if (!test_bit(NETDEV_MCAST_ALL_ON, &vif->flags)) {
|
||||
ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi,
|
||||
vif->fw_vif_idx, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Clear existing WOW patterns */
|
||||
for (i = 0; i < WOW_MAX_FILTERS_PER_LIST; i++)
|
||||
ath6kl_wmi_del_wow_pattern_cmd(ar->wmi, vif->fw_vif_idx,
|
||||
@ -2204,6 +2211,13 @@ static int ath6kl_wow_resume(struct ath6kl *ar)
|
||||
|
||||
ar->state = ATH6KL_STATE_ON;
|
||||
|
||||
if (!test_bit(NETDEV_MCAST_ALL_OFF, &vif->flags)) {
|
||||
ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi,
|
||||
vif->fw_vif_idx, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
netif_wake_queue(vif->ndev);
|
||||
|
||||
return 0;
|
||||
|
@ -510,6 +510,8 @@ enum ath6kl_vif_state {
|
||||
WLAN_ENABLED,
|
||||
STATS_UPDATE_PEND,
|
||||
HOST_SLEEP_MODE_CMD_PROCESSED,
|
||||
NETDEV_MCAST_ALL_ON,
|
||||
NETDEV_MCAST_ALL_OFF,
|
||||
};
|
||||
|
||||
struct ath6kl_vif {
|
||||
|
@ -1145,7 +1145,7 @@ static int ath6kl_set_features(struct net_device *dev,
|
||||
static void ath6kl_set_multicast_list(struct net_device *ndev)
|
||||
{
|
||||
struct ath6kl_vif *vif = netdev_priv(ndev);
|
||||
bool mc_all_on = false, mc_all_off = false;
|
||||
bool mc_all_on = false;
|
||||
int mc_count = netdev_mc_count(ndev);
|
||||
struct netdev_hw_addr *ha;
|
||||
bool found;
|
||||
@ -1157,24 +1157,41 @@ static void ath6kl_set_multicast_list(struct net_device *ndev)
|
||||
!test_bit(WLAN_ENABLED, &vif->flags))
|
||||
return;
|
||||
|
||||
/* Enable multicast-all filter. */
|
||||
mc_all_on = !!(ndev->flags & IFF_PROMISC) ||
|
||||
!!(ndev->flags & IFF_ALLMULTI) ||
|
||||
!!(mc_count > ATH6K_MAX_MC_FILTERS_PER_LIST);
|
||||
|
||||
mc_all_off = !(ndev->flags & IFF_MULTICAST) || mc_count == 0;
|
||||
if (mc_all_on)
|
||||
set_bit(NETDEV_MCAST_ALL_ON, &vif->flags);
|
||||
else
|
||||
clear_bit(NETDEV_MCAST_ALL_ON, &vif->flags);
|
||||
|
||||
if (mc_all_on || mc_all_off) {
|
||||
/* Enable/disable all multicast */
|
||||
ath6kl_dbg(ATH6KL_DBG_TRC, "%s multicast filter\n",
|
||||
mc_all_on ? "enabling" : "disabling");
|
||||
ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi, vif->fw_vif_idx,
|
||||
mc_all_on = mc_all_on || (vif->ar->state == ATH6KL_STATE_ON);
|
||||
|
||||
if (!(ndev->flags & IFF_MULTICAST)) {
|
||||
mc_all_on = false;
|
||||
set_bit(NETDEV_MCAST_ALL_OFF, &vif->flags);
|
||||
} else {
|
||||
clear_bit(NETDEV_MCAST_ALL_OFF, &vif->flags);
|
||||
}
|
||||
|
||||
/* Enable/disable "multicast-all" filter*/
|
||||
ath6kl_dbg(ATH6KL_DBG_TRC, "%s multicast-all filter\n",
|
||||
mc_all_on ? "enabling" : "disabling");
|
||||
|
||||
ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi, vif->fw_vif_idx,
|
||||
mc_all_on);
|
||||
if (ret)
|
||||
ath6kl_warn("Failed to %s multicast receive\n",
|
||||
mc_all_on ? "enable" : "disable");
|
||||
if (ret) {
|
||||
ath6kl_warn("Failed to %s multicast-all receive\n",
|
||||
mc_all_on ? "enable" : "disable");
|
||||
return;
|
||||
}
|
||||
|
||||
if (test_bit(NETDEV_MCAST_ALL_ON, &vif->flags))
|
||||
return;
|
||||
|
||||
/* Keep the driver and firmware mcast list in sync. */
|
||||
list_for_each_entry_safe(mc_filter, tmp, &vif->mc_filter, list) {
|
||||
found = false;
|
||||
netdev_for_each_mc_addr(ha, ndev) {
|
||||
|
Loading…
Reference in New Issue
Block a user