Commit d61bdbf1 authored by John W. Linville's avatar John W. Linville
parents 86c157b3 ac20976d
...@@ -159,9 +159,10 @@ static int ieee80211_change_mtu(struct net_device *dev, int new_mtu) ...@@ -159,9 +159,10 @@ static int ieee80211_change_mtu(struct net_device *dev, int new_mtu)
return 0; return 0;
} }
static int ieee80211_verify_mac(struct ieee80211_local *local, u8 *addr) static int ieee80211_verify_mac(struct ieee80211_sub_if_data *sdata, u8 *addr)
{ {
struct ieee80211_sub_if_data *sdata; struct ieee80211_local *local = sdata->local;
struct ieee80211_sub_if_data *iter;
u64 new, mask, tmp; u64 new, mask, tmp;
u8 *m; u8 *m;
int ret = 0; int ret = 0;
...@@ -181,11 +182,14 @@ static int ieee80211_verify_mac(struct ieee80211_local *local, u8 *addr) ...@@ -181,11 +182,14 @@ static int ieee80211_verify_mac(struct ieee80211_local *local, u8 *addr)
mutex_lock(&local->iflist_mtx); mutex_lock(&local->iflist_mtx);
list_for_each_entry(sdata, &local->interfaces, list) { list_for_each_entry(iter, &local->interfaces, list) {
if (sdata->vif.type == NL80211_IFTYPE_MONITOR) if (iter == sdata)
continue; continue;
m = sdata->vif.addr; if (iter->vif.type == NL80211_IFTYPE_MONITOR)
continue;
m = iter->vif.addr;
tmp = ((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) | tmp = ((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) |
((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) | ((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) |
((u64)m[4] << 1*8) | ((u64)m[5] << 0*8); ((u64)m[4] << 1*8) | ((u64)m[5] << 0*8);
...@@ -209,7 +213,7 @@ static int ieee80211_change_mac(struct net_device *dev, void *addr) ...@@ -209,7 +213,7 @@ static int ieee80211_change_mac(struct net_device *dev, void *addr)
if (ieee80211_sdata_running(sdata)) if (ieee80211_sdata_running(sdata))
return -EBUSY; return -EBUSY;
ret = ieee80211_verify_mac(sdata->local, sa->sa_data); ret = ieee80211_verify_mac(sdata, sa->sa_data);
if (ret) if (ret)
return ret; return ret;
...@@ -474,6 +478,9 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) ...@@ -474,6 +478,9 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
master->control_port_protocol; master->control_port_protocol;
sdata->control_port_no_encrypt = sdata->control_port_no_encrypt =
master->control_port_no_encrypt; master->control_port_no_encrypt;
sdata->vif.cab_queue = master->vif.cab_queue;
memcpy(sdata->vif.hw_queue, master->vif.hw_queue,
sizeof(sdata->vif.hw_queue));
break; break;
} }
case NL80211_IFTYPE_AP: case NL80211_IFTYPE_AP:
...@@ -653,7 +660,11 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) ...@@ -653,7 +660,11 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
ieee80211_recalc_ps(local, -1); ieee80211_recalc_ps(local, -1);
if (dev) { if (sdata->vif.type == NL80211_IFTYPE_MONITOR ||
sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
/* XXX: for AP_VLAN, actually track AP queues */
netif_tx_start_all_queues(dev);
} else if (dev) {
unsigned long flags; unsigned long flags;
int n_acs = IEEE80211_NUM_ACS; int n_acs = IEEE80211_NUM_ACS;
int ac; int ac;
...@@ -1479,7 +1490,17 @@ static void ieee80211_assign_perm_addr(struct ieee80211_local *local, ...@@ -1479,7 +1490,17 @@ static void ieee80211_assign_perm_addr(struct ieee80211_local *local,
break; break;
} }
/*
* Pick address of existing interface in case user changed
* MAC address manually, default to perm_addr.
*/
m = local->hw.wiphy->perm_addr; m = local->hw.wiphy->perm_addr;
list_for_each_entry(sdata, &local->interfaces, list) {
if (sdata->vif.type == NL80211_IFTYPE_MONITOR)
continue;
m = sdata->vif.addr;
break;
}
start = ((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) | start = ((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) |
((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) | ((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) |
((u64)m[4] << 1*8) | ((u64)m[5] << 0*8); ((u64)m[4] << 1*8) | ((u64)m[5] << 0*8);
...@@ -1696,6 +1717,15 @@ void ieee80211_remove_interfaces(struct ieee80211_local *local) ...@@ -1696,6 +1717,15 @@ void ieee80211_remove_interfaces(struct ieee80211_local *local)
ASSERT_RTNL(); ASSERT_RTNL();
/*
* Close all AP_VLAN interfaces first, as otherwise they
* might be closed while the AP interface they belong to
* is closed, causing unregister_netdevice_many() to crash.
*/
list_for_each_entry(sdata, &local->interfaces, list)
if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
dev_close(sdata->dev);
mutex_lock(&local->iflist_mtx); mutex_lock(&local->iflist_mtx);
list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) { list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) {
list_del(&sdata->list); list_del(&sdata->list);
......
...@@ -3321,10 +3321,6 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) ...@@ -3321,10 +3321,6 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
if (WARN_ON_ONCE(!auth_data)) if (WARN_ON_ONCE(!auth_data))
return -EINVAL; return -EINVAL;
if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)
tx_flags = IEEE80211_TX_CTL_REQ_TX_STATUS |
IEEE80211_TX_INTFL_MLME_CONN_TX;
auth_data->tries++; auth_data->tries++;
if (auth_data->tries > IEEE80211_AUTH_MAX_TRIES) { if (auth_data->tries > IEEE80211_AUTH_MAX_TRIES) {
...@@ -3358,6 +3354,10 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) ...@@ -3358,6 +3354,10 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
auth_data->expected_transaction = trans; auth_data->expected_transaction = trans;
} }
if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)
tx_flags = IEEE80211_TX_CTL_REQ_TX_STATUS |
IEEE80211_TX_INTFL_MLME_CONN_TX;
ieee80211_send_auth(sdata, trans, auth_data->algorithm, status, ieee80211_send_auth(sdata, trans, auth_data->algorithm, status,
auth_data->data, auth_data->data_len, auth_data->data, auth_data->data_len,
auth_data->bss->bssid, auth_data->bss->bssid,
...@@ -3381,12 +3381,12 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) ...@@ -3381,12 +3381,12 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
* will not answer to direct packet in unassociated state. * will not answer to direct packet in unassociated state.
*/ */
ieee80211_send_probe_req(sdata, NULL, ssidie + 2, ssidie[1], ieee80211_send_probe_req(sdata, NULL, ssidie + 2, ssidie[1],
NULL, 0, (u32) -1, true, tx_flags, NULL, 0, (u32) -1, true, 0,
auth_data->bss->channel, false); auth_data->bss->channel, false);
rcu_read_unlock(); rcu_read_unlock();
} }
if (!(local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) { if (tx_flags == 0) {
auth_data->timeout = jiffies + IEEE80211_AUTH_TIMEOUT; auth_data->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
ifmgd->auth_data->timeout_started = true; ifmgd->auth_data->timeout_started = true;
run_again(ifmgd, auth_data->timeout); run_again(ifmgd, auth_data->timeout);
......
...@@ -3411,7 +3411,7 @@ static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq, ...@@ -3411,7 +3411,7 @@ static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq,
(u32)sinfo->rx_bytes)) (u32)sinfo->rx_bytes))
goto nla_put_failure; goto nla_put_failure;
if ((sinfo->filled & (STATION_INFO_TX_BYTES | if ((sinfo->filled & (STATION_INFO_TX_BYTES |
NL80211_STA_INFO_TX_BYTES64)) && STATION_INFO_TX_BYTES64)) &&
nla_put_u32(msg, NL80211_STA_INFO_TX_BYTES, nla_put_u32(msg, NL80211_STA_INFO_TX_BYTES,
(u32)sinfo->tx_bytes)) (u32)sinfo->tx_bytes))
goto nla_put_failure; goto nla_put_failure;
......
...@@ -231,6 +231,9 @@ void cfg80211_conn_work(struct work_struct *work) ...@@ -231,6 +231,9 @@ void cfg80211_conn_work(struct work_struct *work)
mutex_lock(&rdev->sched_scan_mtx); mutex_lock(&rdev->sched_scan_mtx);
list_for_each_entry(wdev, &rdev->wdev_list, list) { list_for_each_entry(wdev, &rdev->wdev_list, list) {
if (!wdev->netdev)
continue;
wdev_lock(wdev); wdev_lock(wdev);
if (!netif_running(wdev->netdev)) { if (!netif_running(wdev->netdev)) {
wdev_unlock(wdev); wdev_unlock(wdev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment