diff options
Diffstat (limited to 'net/mac80211/mesh_hwmp.c')
-rw-r--r-- | net/mac80211/mesh_hwmp.c | 230 |
1 files changed, 115 insertions, 115 deletions
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index 08aca446ca01..501c7831adb4 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c | |||
@@ -64,14 +64,14 @@ static inline u32 u32_field_get(u8 *preq_elem, int offset, bool ae) | |||
64 | #define DSN_LT(x, y) ((long) (x) - (long) (y) < 0) | 64 | #define DSN_LT(x, y) ((long) (x) - (long) (y) < 0) |
65 | 65 | ||
66 | #define net_traversal_jiffies(s) \ | 66 | #define net_traversal_jiffies(s) \ |
67 | msecs_to_jiffies(s->u.sta.mshcfg.dot11MeshHWMPnetDiameterTraversalTime) | 67 | msecs_to_jiffies(s->u.mesh.mshcfg.dot11MeshHWMPnetDiameterTraversalTime) |
68 | #define default_lifetime(s) \ | 68 | #define default_lifetime(s) \ |
69 | MSEC_TO_TU(s->u.sta.mshcfg.dot11MeshHWMPactivePathTimeout) | 69 | MSEC_TO_TU(s->u.mesh.mshcfg.dot11MeshHWMPactivePathTimeout) |
70 | #define min_preq_int_jiff(s) \ | 70 | #define min_preq_int_jiff(s) \ |
71 | (msecs_to_jiffies(s->u.sta.mshcfg.dot11MeshHWMPpreqMinInterval)) | 71 | (msecs_to_jiffies(s->u.mesh.mshcfg.dot11MeshHWMPpreqMinInterval)) |
72 | #define max_preq_retries(s) (s->u.sta.mshcfg.dot11MeshHWMPmaxPREQretries) | 72 | #define max_preq_retries(s) (s->u.mesh.mshcfg.dot11MeshHWMPmaxPREQretries) |
73 | #define disc_timeout_jiff(s) \ | 73 | #define disc_timeout_jiff(s) \ |
74 | msecs_to_jiffies(sdata->u.sta.mshcfg.min_discovery_timeout) | 74 | msecs_to_jiffies(sdata->u.mesh.mshcfg.min_discovery_timeout) |
75 | 75 | ||
76 | enum mpath_frame_type { | 76 | enum mpath_frame_type { |
77 | MPATH_PREQ = 0, | 77 | MPATH_PREQ = 0, |
@@ -82,9 +82,9 @@ enum mpath_frame_type { | |||
82 | static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags, | 82 | static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags, |
83 | u8 *orig_addr, __le32 orig_dsn, u8 dst_flags, u8 *dst, | 83 | u8 *orig_addr, __le32 orig_dsn, u8 dst_flags, u8 *dst, |
84 | __le32 dst_dsn, u8 *da, u8 hop_count, u8 ttl, __le32 lifetime, | 84 | __le32 dst_dsn, u8 *da, u8 hop_count, u8 ttl, __le32 lifetime, |
85 | __le32 metric, __le32 preq_id, struct net_device *dev) | 85 | __le32 metric, __le32 preq_id, struct ieee80211_sub_if_data *sdata) |
86 | { | 86 | { |
87 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 87 | struct ieee80211_local *local = sdata->local; |
88 | struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); | 88 | struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); |
89 | struct ieee80211_mgmt *mgmt; | 89 | struct ieee80211_mgmt *mgmt; |
90 | u8 *pos; | 90 | u8 *pos; |
@@ -99,11 +99,11 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags, | |||
99 | mgmt = (struct ieee80211_mgmt *) | 99 | mgmt = (struct ieee80211_mgmt *) |
100 | skb_put(skb, 25 + sizeof(mgmt->u.action.u.mesh_action)); | 100 | skb_put(skb, 25 + sizeof(mgmt->u.action.u.mesh_action)); |
101 | memset(mgmt, 0, 25 + sizeof(mgmt->u.action.u.mesh_action)); | 101 | memset(mgmt, 0, 25 + sizeof(mgmt->u.action.u.mesh_action)); |
102 | mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT, | 102 | mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | |
103 | IEEE80211_STYPE_ACTION); | 103 | IEEE80211_STYPE_ACTION); |
104 | 104 | ||
105 | memcpy(mgmt->da, da, ETH_ALEN); | 105 | memcpy(mgmt->da, da, ETH_ALEN); |
106 | memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN); | 106 | memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); |
107 | /* BSSID is left zeroed, wildcard value */ | 107 | /* BSSID is left zeroed, wildcard value */ |
108 | mgmt->u.action.category = MESH_PATH_SEL_CATEGORY; | 108 | mgmt->u.action.category = MESH_PATH_SEL_CATEGORY; |
109 | mgmt->u.action.u.mesh_action.action_code = action; | 109 | mgmt->u.action.u.mesh_action.action_code = action; |
@@ -149,7 +149,7 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags, | |||
149 | pos += ETH_ALEN; | 149 | pos += ETH_ALEN; |
150 | memcpy(pos, &dst_dsn, 4); | 150 | memcpy(pos, &dst_dsn, 4); |
151 | 151 | ||
152 | ieee80211_sta_tx(dev, skb, 0); | 152 | ieee80211_tx_skb(sdata, skb, 0); |
153 | return 0; | 153 | return 0; |
154 | } | 154 | } |
155 | 155 | ||
@@ -161,9 +161,9 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags, | |||
161 | * @ra: node this frame is addressed to | 161 | * @ra: node this frame is addressed to |
162 | */ | 162 | */ |
163 | int mesh_path_error_tx(u8 *dst, __le32 dst_dsn, u8 *ra, | 163 | int mesh_path_error_tx(u8 *dst, __le32 dst_dsn, u8 *ra, |
164 | struct net_device *dev) | 164 | struct ieee80211_sub_if_data *sdata) |
165 | { | 165 | { |
166 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 166 | struct ieee80211_local *local = sdata->local; |
167 | struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); | 167 | struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); |
168 | struct ieee80211_mgmt *mgmt; | 168 | struct ieee80211_mgmt *mgmt; |
169 | u8 *pos; | 169 | u8 *pos; |
@@ -178,11 +178,11 @@ int mesh_path_error_tx(u8 *dst, __le32 dst_dsn, u8 *ra, | |||
178 | mgmt = (struct ieee80211_mgmt *) | 178 | mgmt = (struct ieee80211_mgmt *) |
179 | skb_put(skb, 25 + sizeof(mgmt->u.action.u.mesh_action)); | 179 | skb_put(skb, 25 + sizeof(mgmt->u.action.u.mesh_action)); |
180 | memset(mgmt, 0, 25 + sizeof(mgmt->u.action.u.mesh_action)); | 180 | memset(mgmt, 0, 25 + sizeof(mgmt->u.action.u.mesh_action)); |
181 | mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT, | 181 | mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | |
182 | IEEE80211_STYPE_ACTION); | 182 | IEEE80211_STYPE_ACTION); |
183 | 183 | ||
184 | memcpy(mgmt->da, ra, ETH_ALEN); | 184 | memcpy(mgmt->da, ra, ETH_ALEN); |
185 | memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN); | 185 | memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); |
186 | /* BSSID is left zeroed, wildcard value */ | 186 | /* BSSID is left zeroed, wildcard value */ |
187 | mgmt->u.action.category = MESH_PATH_SEL_CATEGORY; | 187 | mgmt->u.action.category = MESH_PATH_SEL_CATEGORY; |
188 | mgmt->u.action.u.mesh_action.action_code = MPATH_PERR; | 188 | mgmt->u.action.u.mesh_action.action_code = MPATH_PERR; |
@@ -198,7 +198,7 @@ int mesh_path_error_tx(u8 *dst, __le32 dst_dsn, u8 *ra, | |||
198 | pos += ETH_ALEN; | 198 | pos += ETH_ALEN; |
199 | memcpy(pos, &dst_dsn, 4); | 199 | memcpy(pos, &dst_dsn, 4); |
200 | 200 | ||
201 | ieee80211_sta_tx(dev, skb, 0); | 201 | ieee80211_tx_skb(sdata, skb, 0); |
202 | return 0; | 202 | return 0; |
203 | } | 203 | } |
204 | 204 | ||
@@ -223,7 +223,7 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local, | |||
223 | /* bitrate is in units of 100 Kbps, while we need rate in units of | 223 | /* bitrate is in units of 100 Kbps, while we need rate in units of |
224 | * 1Mbps. This will be corrected on tx_time computation. | 224 | * 1Mbps. This will be corrected on tx_time computation. |
225 | */ | 225 | */ |
226 | rate = sband->bitrates[sta->txrate_idx].bitrate; | 226 | rate = sband->bitrates[sta->last_txrate_idx].bitrate; |
227 | tx_time = (device_constant + 10 * test_frame_len / rate); | 227 | tx_time = (device_constant + 10 * test_frame_len / rate); |
228 | estimated_retx = ((1 << (2 * ARITH_SHIFT)) / (s_unit - err)); | 228 | estimated_retx = ((1 << (2 * ARITH_SHIFT)) / (s_unit - err)); |
229 | result = (tx_time * estimated_retx) >> (2 * ARITH_SHIFT) ; | 229 | result = (tx_time * estimated_retx) >> (2 * ARITH_SHIFT) ; |
@@ -233,7 +233,7 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local, | |||
233 | /** | 233 | /** |
234 | * hwmp_route_info_get - Update routing info to originator and transmitter | 234 | * hwmp_route_info_get - Update routing info to originator and transmitter |
235 | * | 235 | * |
236 | * @dev: local mesh interface | 236 | * @sdata: local mesh subif |
237 | * @mgmt: mesh management frame | 237 | * @mgmt: mesh management frame |
238 | * @hwmp_ie: hwmp information element (PREP or PREQ) | 238 | * @hwmp_ie: hwmp information element (PREP or PREQ) |
239 | * | 239 | * |
@@ -246,11 +246,11 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local, | |||
246 | * Notes: this function is the only place (besides user-provided info) where | 246 | * Notes: this function is the only place (besides user-provided info) where |
247 | * path routing information is updated. | 247 | * path routing information is updated. |
248 | */ | 248 | */ |
249 | static u32 hwmp_route_info_get(struct net_device *dev, | 249 | static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata, |
250 | struct ieee80211_mgmt *mgmt, | 250 | struct ieee80211_mgmt *mgmt, |
251 | u8 *hwmp_ie) | 251 | u8 *hwmp_ie) |
252 | { | 252 | { |
253 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 253 | struct ieee80211_local *local = sdata->local; |
254 | struct mesh_path *mpath; | 254 | struct mesh_path *mpath; |
255 | struct sta_info *sta; | 255 | struct sta_info *sta; |
256 | bool fresh_info; | 256 | bool fresh_info; |
@@ -301,14 +301,14 @@ static u32 hwmp_route_info_get(struct net_device *dev, | |||
301 | new_metric = MAX_METRIC; | 301 | new_metric = MAX_METRIC; |
302 | exp_time = TU_TO_EXP_TIME(orig_lifetime); | 302 | exp_time = TU_TO_EXP_TIME(orig_lifetime); |
303 | 303 | ||
304 | if (memcmp(orig_addr, dev->dev_addr, ETH_ALEN) == 0) { | 304 | if (memcmp(orig_addr, sdata->dev->dev_addr, ETH_ALEN) == 0) { |
305 | /* This MP is the originator, we are not interested in this | 305 | /* This MP is the originator, we are not interested in this |
306 | * frame, except for updating transmitter's path info. | 306 | * frame, except for updating transmitter's path info. |
307 | */ | 307 | */ |
308 | process = false; | 308 | process = false; |
309 | fresh_info = false; | 309 | fresh_info = false; |
310 | } else { | 310 | } else { |
311 | mpath = mesh_path_lookup(orig_addr, dev); | 311 | mpath = mesh_path_lookup(orig_addr, sdata); |
312 | if (mpath) { | 312 | if (mpath) { |
313 | spin_lock_bh(&mpath->state_lock); | 313 | spin_lock_bh(&mpath->state_lock); |
314 | if (mpath->flags & MESH_PATH_FIXED) | 314 | if (mpath->flags & MESH_PATH_FIXED) |
@@ -324,8 +324,8 @@ static u32 hwmp_route_info_get(struct net_device *dev, | |||
324 | } | 324 | } |
325 | } | 325 | } |
326 | } else { | 326 | } else { |
327 | mesh_path_add(orig_addr, dev); | 327 | mesh_path_add(orig_addr, sdata); |
328 | mpath = mesh_path_lookup(orig_addr, dev); | 328 | mpath = mesh_path_lookup(orig_addr, sdata); |
329 | if (!mpath) { | 329 | if (!mpath) { |
330 | rcu_read_unlock(); | 330 | rcu_read_unlock(); |
331 | return 0; | 331 | return 0; |
@@ -357,7 +357,7 @@ static u32 hwmp_route_info_get(struct net_device *dev, | |||
357 | else { | 357 | else { |
358 | fresh_info = true; | 358 | fresh_info = true; |
359 | 359 | ||
360 | mpath = mesh_path_lookup(ta, dev); | 360 | mpath = mesh_path_lookup(ta, sdata); |
361 | if (mpath) { | 361 | if (mpath) { |
362 | spin_lock_bh(&mpath->state_lock); | 362 | spin_lock_bh(&mpath->state_lock); |
363 | if ((mpath->flags & MESH_PATH_FIXED) || | 363 | if ((mpath->flags & MESH_PATH_FIXED) || |
@@ -365,8 +365,8 @@ static u32 hwmp_route_info_get(struct net_device *dev, | |||
365 | (last_hop_metric > mpath->metric))) | 365 | (last_hop_metric > mpath->metric))) |
366 | fresh_info = false; | 366 | fresh_info = false; |
367 | } else { | 367 | } else { |
368 | mesh_path_add(ta, dev); | 368 | mesh_path_add(ta, sdata); |
369 | mpath = mesh_path_lookup(ta, dev); | 369 | mpath = mesh_path_lookup(ta, sdata); |
370 | if (!mpath) { | 370 | if (!mpath) { |
371 | rcu_read_unlock(); | 371 | rcu_read_unlock(); |
372 | return 0; | 372 | return 0; |
@@ -392,11 +392,10 @@ static u32 hwmp_route_info_get(struct net_device *dev, | |||
392 | return process ? new_metric : 0; | 392 | return process ? new_metric : 0; |
393 | } | 393 | } |
394 | 394 | ||
395 | static void hwmp_preq_frame_process(struct net_device *dev, | 395 | static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, |
396 | struct ieee80211_mgmt *mgmt, | 396 | struct ieee80211_mgmt *mgmt, |
397 | u8 *preq_elem, u32 metric) { | 397 | u8 *preq_elem, u32 metric) { |
398 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 398 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; |
399 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; | ||
400 | struct mesh_path *mpath; | 399 | struct mesh_path *mpath; |
401 | u8 *dst_addr, *orig_addr; | 400 | u8 *dst_addr, *orig_addr; |
402 | u8 dst_flags, ttl; | 401 | u8 dst_flags, ttl; |
@@ -411,19 +410,19 @@ static void hwmp_preq_frame_process(struct net_device *dev, | |||
411 | orig_dsn = PREQ_IE_ORIG_DSN(preq_elem); | 410 | orig_dsn = PREQ_IE_ORIG_DSN(preq_elem); |
412 | dst_flags = PREQ_IE_DST_F(preq_elem); | 411 | dst_flags = PREQ_IE_DST_F(preq_elem); |
413 | 412 | ||
414 | if (memcmp(dst_addr, dev->dev_addr, ETH_ALEN) == 0) { | 413 | if (memcmp(dst_addr, sdata->dev->dev_addr, ETH_ALEN) == 0) { |
415 | forward = false; | 414 | forward = false; |
416 | reply = true; | 415 | reply = true; |
417 | metric = 0; | 416 | metric = 0; |
418 | if (time_after(jiffies, ifsta->last_dsn_update + | 417 | if (time_after(jiffies, ifmsh->last_dsn_update + |
419 | net_traversal_jiffies(sdata)) || | 418 | net_traversal_jiffies(sdata)) || |
420 | time_before(jiffies, ifsta->last_dsn_update)) { | 419 | time_before(jiffies, ifmsh->last_dsn_update)) { |
421 | dst_dsn = ++ifsta->dsn; | 420 | dst_dsn = ++ifmsh->dsn; |
422 | ifsta->last_dsn_update = jiffies; | 421 | ifmsh->last_dsn_update = jiffies; |
423 | } | 422 | } |
424 | } else { | 423 | } else { |
425 | rcu_read_lock(); | 424 | rcu_read_lock(); |
426 | mpath = mesh_path_lookup(dst_addr, dev); | 425 | mpath = mesh_path_lookup(dst_addr, sdata); |
427 | if (mpath) { | 426 | if (mpath) { |
428 | if ((!(mpath->flags & MESH_PATH_DSN_VALID)) || | 427 | if ((!(mpath->flags & MESH_PATH_DSN_VALID)) || |
429 | DSN_LT(mpath->dsn, dst_dsn)) { | 428 | DSN_LT(mpath->dsn, dst_dsn)) { |
@@ -445,15 +444,15 @@ static void hwmp_preq_frame_process(struct net_device *dev, | |||
445 | 444 | ||
446 | if (reply) { | 445 | if (reply) { |
447 | lifetime = PREQ_IE_LIFETIME(preq_elem); | 446 | lifetime = PREQ_IE_LIFETIME(preq_elem); |
448 | ttl = ifsta->mshcfg.dot11MeshTTL; | 447 | ttl = ifmsh->mshcfg.dot11MeshTTL; |
449 | if (ttl != 0) | 448 | if (ttl != 0) |
450 | mesh_path_sel_frame_tx(MPATH_PREP, 0, dst_addr, | 449 | mesh_path_sel_frame_tx(MPATH_PREP, 0, dst_addr, |
451 | cpu_to_le32(dst_dsn), 0, orig_addr, | 450 | cpu_to_le32(dst_dsn), 0, orig_addr, |
452 | cpu_to_le32(orig_dsn), mgmt->sa, 0, ttl, | 451 | cpu_to_le32(orig_dsn), mgmt->sa, 0, ttl, |
453 | cpu_to_le32(lifetime), cpu_to_le32(metric), | 452 | cpu_to_le32(lifetime), cpu_to_le32(metric), |
454 | 0, dev); | 453 | 0, sdata); |
455 | else | 454 | else |
456 | ifsta->mshstats.dropped_frames_ttl++; | 455 | ifmsh->mshstats.dropped_frames_ttl++; |
457 | } | 456 | } |
458 | 457 | ||
459 | if (forward) { | 458 | if (forward) { |
@@ -463,7 +462,7 @@ static void hwmp_preq_frame_process(struct net_device *dev, | |||
463 | ttl = PREQ_IE_TTL(preq_elem); | 462 | ttl = PREQ_IE_TTL(preq_elem); |
464 | lifetime = PREQ_IE_LIFETIME(preq_elem); | 463 | lifetime = PREQ_IE_LIFETIME(preq_elem); |
465 | if (ttl <= 1) { | 464 | if (ttl <= 1) { |
466 | ifsta->mshstats.dropped_frames_ttl++; | 465 | ifmsh->mshstats.dropped_frames_ttl++; |
467 | return; | 466 | return; |
468 | } | 467 | } |
469 | --ttl; | 468 | --ttl; |
@@ -472,20 +471,19 @@ static void hwmp_preq_frame_process(struct net_device *dev, | |||
472 | hopcount = PREQ_IE_HOPCOUNT(preq_elem) + 1; | 471 | hopcount = PREQ_IE_HOPCOUNT(preq_elem) + 1; |
473 | mesh_path_sel_frame_tx(MPATH_PREQ, flags, orig_addr, | 472 | mesh_path_sel_frame_tx(MPATH_PREQ, flags, orig_addr, |
474 | cpu_to_le32(orig_dsn), dst_flags, dst_addr, | 473 | cpu_to_le32(orig_dsn), dst_flags, dst_addr, |
475 | cpu_to_le32(dst_dsn), dev->broadcast, | 474 | cpu_to_le32(dst_dsn), sdata->dev->broadcast, |
476 | hopcount, ttl, cpu_to_le32(lifetime), | 475 | hopcount, ttl, cpu_to_le32(lifetime), |
477 | cpu_to_le32(metric), cpu_to_le32(preq_id), | 476 | cpu_to_le32(metric), cpu_to_le32(preq_id), |
478 | dev); | 477 | sdata); |
479 | ifsta->mshstats.fwded_frames++; | 478 | ifmsh->mshstats.fwded_frames++; |
480 | } | 479 | } |
481 | } | 480 | } |
482 | 481 | ||
483 | 482 | ||
484 | static void hwmp_prep_frame_process(struct net_device *dev, | 483 | static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata, |
485 | struct ieee80211_mgmt *mgmt, | 484 | struct ieee80211_mgmt *mgmt, |
486 | u8 *prep_elem, u32 metric) | 485 | u8 *prep_elem, u32 metric) |
487 | { | 486 | { |
488 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
489 | struct mesh_path *mpath; | 487 | struct mesh_path *mpath; |
490 | u8 *dst_addr, *orig_addr; | 488 | u8 *dst_addr, *orig_addr; |
491 | u8 ttl, hopcount, flags; | 489 | u8 ttl, hopcount, flags; |
@@ -499,18 +497,18 @@ static void hwmp_prep_frame_process(struct net_device *dev, | |||
499 | * replies | 497 | * replies |
500 | */ | 498 | */ |
501 | dst_addr = PREP_IE_DST_ADDR(prep_elem); | 499 | dst_addr = PREP_IE_DST_ADDR(prep_elem); |
502 | if (memcmp(dst_addr, dev->dev_addr, ETH_ALEN) == 0) | 500 | if (memcmp(dst_addr, sdata->dev->dev_addr, ETH_ALEN) == 0) |
503 | /* destination, no forwarding required */ | 501 | /* destination, no forwarding required */ |
504 | return; | 502 | return; |
505 | 503 | ||
506 | ttl = PREP_IE_TTL(prep_elem); | 504 | ttl = PREP_IE_TTL(prep_elem); |
507 | if (ttl <= 1) { | 505 | if (ttl <= 1) { |
508 | sdata->u.sta.mshstats.dropped_frames_ttl++; | 506 | sdata->u.mesh.mshstats.dropped_frames_ttl++; |
509 | return; | 507 | return; |
510 | } | 508 | } |
511 | 509 | ||
512 | rcu_read_lock(); | 510 | rcu_read_lock(); |
513 | mpath = mesh_path_lookup(dst_addr, dev); | 511 | mpath = mesh_path_lookup(dst_addr, sdata); |
514 | if (mpath) | 512 | if (mpath) |
515 | spin_lock_bh(&mpath->state_lock); | 513 | spin_lock_bh(&mpath->state_lock); |
516 | else | 514 | else |
@@ -519,7 +517,7 @@ static void hwmp_prep_frame_process(struct net_device *dev, | |||
519 | spin_unlock_bh(&mpath->state_lock); | 517 | spin_unlock_bh(&mpath->state_lock); |
520 | goto fail; | 518 | goto fail; |
521 | } | 519 | } |
522 | memcpy(next_hop, mpath->next_hop->addr, ETH_ALEN); | 520 | memcpy(next_hop, mpath->next_hop->sta.addr, ETH_ALEN); |
523 | spin_unlock_bh(&mpath->state_lock); | 521 | spin_unlock_bh(&mpath->state_lock); |
524 | --ttl; | 522 | --ttl; |
525 | flags = PREP_IE_FLAGS(prep_elem); | 523 | flags = PREP_IE_FLAGS(prep_elem); |
@@ -531,20 +529,20 @@ static void hwmp_prep_frame_process(struct net_device *dev, | |||
531 | 529 | ||
532 | mesh_path_sel_frame_tx(MPATH_PREP, flags, orig_addr, | 530 | mesh_path_sel_frame_tx(MPATH_PREP, flags, orig_addr, |
533 | cpu_to_le32(orig_dsn), 0, dst_addr, | 531 | cpu_to_le32(orig_dsn), 0, dst_addr, |
534 | cpu_to_le32(dst_dsn), mpath->next_hop->addr, hopcount, ttl, | 532 | cpu_to_le32(dst_dsn), mpath->next_hop->sta.addr, hopcount, ttl, |
535 | cpu_to_le32(lifetime), cpu_to_le32(metric), | 533 | cpu_to_le32(lifetime), cpu_to_le32(metric), |
536 | 0, dev); | 534 | 0, sdata); |
537 | rcu_read_unlock(); | 535 | rcu_read_unlock(); |
538 | sdata->u.sta.mshstats.fwded_frames++; | 536 | sdata->u.mesh.mshstats.fwded_frames++; |
539 | return; | 537 | return; |
540 | 538 | ||
541 | fail: | 539 | fail: |
542 | rcu_read_unlock(); | 540 | rcu_read_unlock(); |
543 | sdata->u.sta.mshstats.dropped_frames_no_route++; | 541 | sdata->u.mesh.mshstats.dropped_frames_no_route++; |
544 | return; | 542 | return; |
545 | } | 543 | } |
546 | 544 | ||
547 | static void hwmp_perr_frame_process(struct net_device *dev, | 545 | static void hwmp_perr_frame_process(struct ieee80211_sub_if_data *sdata, |
548 | struct ieee80211_mgmt *mgmt, u8 *perr_elem) | 546 | struct ieee80211_mgmt *mgmt, u8 *perr_elem) |
549 | { | 547 | { |
550 | struct mesh_path *mpath; | 548 | struct mesh_path *mpath; |
@@ -555,18 +553,18 @@ static void hwmp_perr_frame_process(struct net_device *dev, | |||
555 | dst_addr = PERR_IE_DST_ADDR(perr_elem); | 553 | dst_addr = PERR_IE_DST_ADDR(perr_elem); |
556 | dst_dsn = PERR_IE_DST_DSN(perr_elem); | 554 | dst_dsn = PERR_IE_DST_DSN(perr_elem); |
557 | rcu_read_lock(); | 555 | rcu_read_lock(); |
558 | mpath = mesh_path_lookup(dst_addr, dev); | 556 | mpath = mesh_path_lookup(dst_addr, sdata); |
559 | if (mpath) { | 557 | if (mpath) { |
560 | spin_lock_bh(&mpath->state_lock); | 558 | spin_lock_bh(&mpath->state_lock); |
561 | if (mpath->flags & MESH_PATH_ACTIVE && | 559 | if (mpath->flags & MESH_PATH_ACTIVE && |
562 | memcmp(ta, mpath->next_hop->addr, ETH_ALEN) == 0 && | 560 | memcmp(ta, mpath->next_hop->sta.addr, ETH_ALEN) == 0 && |
563 | (!(mpath->flags & MESH_PATH_DSN_VALID) || | 561 | (!(mpath->flags & MESH_PATH_DSN_VALID) || |
564 | DSN_GT(dst_dsn, mpath->dsn))) { | 562 | DSN_GT(dst_dsn, mpath->dsn))) { |
565 | mpath->flags &= ~MESH_PATH_ACTIVE; | 563 | mpath->flags &= ~MESH_PATH_ACTIVE; |
566 | mpath->dsn = dst_dsn; | 564 | mpath->dsn = dst_dsn; |
567 | spin_unlock_bh(&mpath->state_lock); | 565 | spin_unlock_bh(&mpath->state_lock); |
568 | mesh_path_error_tx(dst_addr, cpu_to_le32(dst_dsn), | 566 | mesh_path_error_tx(dst_addr, cpu_to_le32(dst_dsn), |
569 | dev->broadcast, dev); | 567 | sdata->dev->broadcast, sdata); |
570 | } else | 568 | } else |
571 | spin_unlock_bh(&mpath->state_lock); | 569 | spin_unlock_bh(&mpath->state_lock); |
572 | } | 570 | } |
@@ -575,7 +573,7 @@ static void hwmp_perr_frame_process(struct net_device *dev, | |||
575 | 573 | ||
576 | 574 | ||
577 | 575 | ||
578 | void mesh_rx_path_sel_frame(struct net_device *dev, | 576 | void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata, |
579 | struct ieee80211_mgmt *mgmt, | 577 | struct ieee80211_mgmt *mgmt, |
580 | size_t len) | 578 | size_t len) |
581 | { | 579 | { |
@@ -583,6 +581,10 @@ void mesh_rx_path_sel_frame(struct net_device *dev, | |||
583 | size_t baselen; | 581 | size_t baselen; |
584 | u32 last_hop_metric; | 582 | u32 last_hop_metric; |
585 | 583 | ||
584 | /* need action_code */ | ||
585 | if (len < IEEE80211_MIN_ACTION_SIZE + 1) | ||
586 | return; | ||
587 | |||
586 | baselen = (u8 *) mgmt->u.action.u.mesh_action.variable - (u8 *) mgmt; | 588 | baselen = (u8 *) mgmt->u.action.u.mesh_action.variable - (u8 *) mgmt; |
587 | ieee802_11_parse_elems(mgmt->u.action.u.mesh_action.variable, | 589 | ieee802_11_parse_elems(mgmt->u.action.u.mesh_action.variable, |
588 | len - baselen, &elems); | 590 | len - baselen, &elems); |
@@ -592,25 +594,25 @@ void mesh_rx_path_sel_frame(struct net_device *dev, | |||
592 | if (!elems.preq || elems.preq_len != 37) | 594 | if (!elems.preq || elems.preq_len != 37) |
593 | /* Right now we support just 1 destination and no AE */ | 595 | /* Right now we support just 1 destination and no AE */ |
594 | return; | 596 | return; |
595 | last_hop_metric = hwmp_route_info_get(dev, mgmt, elems.preq); | 597 | last_hop_metric = hwmp_route_info_get(sdata, mgmt, elems.preq); |
596 | if (!last_hop_metric) | 598 | if (!last_hop_metric) |
597 | return; | 599 | return; |
598 | hwmp_preq_frame_process(dev, mgmt, elems.preq, last_hop_metric); | 600 | hwmp_preq_frame_process(sdata, mgmt, elems.preq, last_hop_metric); |
599 | break; | 601 | break; |
600 | case MPATH_PREP: | 602 | case MPATH_PREP: |
601 | if (!elems.prep || elems.prep_len != 31) | 603 | if (!elems.prep || elems.prep_len != 31) |
602 | /* Right now we support no AE */ | 604 | /* Right now we support no AE */ |
603 | return; | 605 | return; |
604 | last_hop_metric = hwmp_route_info_get(dev, mgmt, elems.prep); | 606 | last_hop_metric = hwmp_route_info_get(sdata, mgmt, elems.prep); |
605 | if (!last_hop_metric) | 607 | if (!last_hop_metric) |
606 | return; | 608 | return; |
607 | hwmp_prep_frame_process(dev, mgmt, elems.prep, last_hop_metric); | 609 | hwmp_prep_frame_process(sdata, mgmt, elems.prep, last_hop_metric); |
608 | break; | 610 | break; |
609 | case MPATH_PERR: | 611 | case MPATH_PERR: |
610 | if (!elems.perr || elems.perr_len != 12) | 612 | if (!elems.perr || elems.perr_len != 12) |
611 | /* Right now we support only one destination per PERR */ | 613 | /* Right now we support only one destination per PERR */ |
612 | return; | 614 | return; |
613 | hwmp_perr_frame_process(dev, mgmt, elems.perr); | 615 | hwmp_perr_frame_process(sdata, mgmt, elems.perr); |
614 | default: | 616 | default: |
615 | return; | 617 | return; |
616 | } | 618 | } |
@@ -628,9 +630,8 @@ void mesh_rx_path_sel_frame(struct net_device *dev, | |||
628 | */ | 630 | */ |
629 | static void mesh_queue_preq(struct mesh_path *mpath, u8 flags) | 631 | static void mesh_queue_preq(struct mesh_path *mpath, u8 flags) |
630 | { | 632 | { |
631 | struct ieee80211_sub_if_data *sdata = | 633 | struct ieee80211_sub_if_data *sdata = mpath->sdata; |
632 | IEEE80211_DEV_TO_SUB_IF(mpath->dev); | 634 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; |
633 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; | ||
634 | struct mesh_preq_queue *preq_node; | 635 | struct mesh_preq_queue *preq_node; |
635 | 636 | ||
636 | preq_node = kmalloc(sizeof(struct mesh_preq_queue), GFP_KERNEL); | 637 | preq_node = kmalloc(sizeof(struct mesh_preq_queue), GFP_KERNEL); |
@@ -639,9 +640,9 @@ static void mesh_queue_preq(struct mesh_path *mpath, u8 flags) | |||
639 | return; | 640 | return; |
640 | } | 641 | } |
641 | 642 | ||
642 | spin_lock(&ifsta->mesh_preq_queue_lock); | 643 | spin_lock(&ifmsh->mesh_preq_queue_lock); |
643 | if (ifsta->preq_queue_len == MAX_PREQ_QUEUE_LEN) { | 644 | if (ifmsh->preq_queue_len == MAX_PREQ_QUEUE_LEN) { |
644 | spin_unlock(&ifsta->mesh_preq_queue_lock); | 645 | spin_unlock(&ifmsh->mesh_preq_queue_lock); |
645 | kfree(preq_node); | 646 | kfree(preq_node); |
646 | if (printk_ratelimit()) | 647 | if (printk_ratelimit()) |
647 | printk(KERN_DEBUG "Mesh HWMP: PREQ node queue full\n"); | 648 | printk(KERN_DEBUG "Mesh HWMP: PREQ node queue full\n"); |
@@ -651,55 +652,53 @@ static void mesh_queue_preq(struct mesh_path *mpath, u8 flags) | |||
651 | memcpy(preq_node->dst, mpath->dst, ETH_ALEN); | 652 | memcpy(preq_node->dst, mpath->dst, ETH_ALEN); |
652 | preq_node->flags = flags; | 653 | preq_node->flags = flags; |
653 | 654 | ||
654 | list_add_tail(&preq_node->list, &ifsta->preq_queue.list); | 655 | list_add_tail(&preq_node->list, &ifmsh->preq_queue.list); |
655 | ++ifsta->preq_queue_len; | 656 | ++ifmsh->preq_queue_len; |
656 | spin_unlock(&ifsta->mesh_preq_queue_lock); | 657 | spin_unlock(&ifmsh->mesh_preq_queue_lock); |
657 | 658 | ||
658 | if (time_after(jiffies, ifsta->last_preq + min_preq_int_jiff(sdata))) | 659 | if (time_after(jiffies, ifmsh->last_preq + min_preq_int_jiff(sdata))) |
659 | queue_work(sdata->local->hw.workqueue, &ifsta->work); | 660 | queue_work(sdata->local->hw.workqueue, &ifmsh->work); |
660 | 661 | ||
661 | else if (time_before(jiffies, ifsta->last_preq)) { | 662 | else if (time_before(jiffies, ifmsh->last_preq)) { |
662 | /* avoid long wait if did not send preqs for a long time | 663 | /* avoid long wait if did not send preqs for a long time |
663 | * and jiffies wrapped around | 664 | * and jiffies wrapped around |
664 | */ | 665 | */ |
665 | ifsta->last_preq = jiffies - min_preq_int_jiff(sdata) - 1; | 666 | ifmsh->last_preq = jiffies - min_preq_int_jiff(sdata) - 1; |
666 | queue_work(sdata->local->hw.workqueue, &ifsta->work); | 667 | queue_work(sdata->local->hw.workqueue, &ifmsh->work); |
667 | } else | 668 | } else |
668 | mod_timer(&ifsta->mesh_path_timer, ifsta->last_preq + | 669 | mod_timer(&ifmsh->mesh_path_timer, ifmsh->last_preq + |
669 | min_preq_int_jiff(sdata)); | 670 | min_preq_int_jiff(sdata)); |
670 | } | 671 | } |
671 | 672 | ||
672 | /** | 673 | /** |
673 | * mesh_path_start_discovery - launch a path discovery from the PREQ queue | 674 | * mesh_path_start_discovery - launch a path discovery from the PREQ queue |
674 | * | 675 | * |
675 | * @dev: local mesh interface | 676 | * @sdata: local mesh subif |
676 | */ | 677 | */ |
677 | void mesh_path_start_discovery(struct net_device *dev) | 678 | void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata) |
678 | { | 679 | { |
679 | struct ieee80211_sub_if_data *sdata = | 680 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; |
680 | IEEE80211_DEV_TO_SUB_IF(dev); | ||
681 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; | ||
682 | struct mesh_preq_queue *preq_node; | 681 | struct mesh_preq_queue *preq_node; |
683 | struct mesh_path *mpath; | 682 | struct mesh_path *mpath; |
684 | u8 ttl, dst_flags; | 683 | u8 ttl, dst_flags; |
685 | u32 lifetime; | 684 | u32 lifetime; |
686 | 685 | ||
687 | spin_lock(&ifsta->mesh_preq_queue_lock); | 686 | spin_lock(&ifmsh->mesh_preq_queue_lock); |
688 | if (!ifsta->preq_queue_len || | 687 | if (!ifmsh->preq_queue_len || |
689 | time_before(jiffies, ifsta->last_preq + | 688 | time_before(jiffies, ifmsh->last_preq + |
690 | min_preq_int_jiff(sdata))) { | 689 | min_preq_int_jiff(sdata))) { |
691 | spin_unlock(&ifsta->mesh_preq_queue_lock); | 690 | spin_unlock(&ifmsh->mesh_preq_queue_lock); |
692 | return; | 691 | return; |
693 | } | 692 | } |
694 | 693 | ||
695 | preq_node = list_first_entry(&ifsta->preq_queue.list, | 694 | preq_node = list_first_entry(&ifmsh->preq_queue.list, |
696 | struct mesh_preq_queue, list); | 695 | struct mesh_preq_queue, list); |
697 | list_del(&preq_node->list); | 696 | list_del(&preq_node->list); |
698 | --ifsta->preq_queue_len; | 697 | --ifmsh->preq_queue_len; |
699 | spin_unlock(&ifsta->mesh_preq_queue_lock); | 698 | spin_unlock(&ifmsh->mesh_preq_queue_lock); |
700 | 699 | ||
701 | rcu_read_lock(); | 700 | rcu_read_lock(); |
702 | mpath = mesh_path_lookup(preq_node->dst, dev); | 701 | mpath = mesh_path_lookup(preq_node->dst, sdata); |
703 | if (!mpath) | 702 | if (!mpath) |
704 | goto enddiscovery; | 703 | goto enddiscovery; |
705 | 704 | ||
@@ -721,18 +720,18 @@ void mesh_path_start_discovery(struct net_device *dev) | |||
721 | goto enddiscovery; | 720 | goto enddiscovery; |
722 | } | 721 | } |
723 | 722 | ||
724 | ifsta->last_preq = jiffies; | 723 | ifmsh->last_preq = jiffies; |
725 | 724 | ||
726 | if (time_after(jiffies, ifsta->last_dsn_update + | 725 | if (time_after(jiffies, ifmsh->last_dsn_update + |
727 | net_traversal_jiffies(sdata)) || | 726 | net_traversal_jiffies(sdata)) || |
728 | time_before(jiffies, ifsta->last_dsn_update)) { | 727 | time_before(jiffies, ifmsh->last_dsn_update)) { |
729 | ++ifsta->dsn; | 728 | ++ifmsh->dsn; |
730 | sdata->u.sta.last_dsn_update = jiffies; | 729 | sdata->u.mesh.last_dsn_update = jiffies; |
731 | } | 730 | } |
732 | lifetime = default_lifetime(sdata); | 731 | lifetime = default_lifetime(sdata); |
733 | ttl = sdata->u.sta.mshcfg.dot11MeshTTL; | 732 | ttl = sdata->u.mesh.mshcfg.dot11MeshTTL; |
734 | if (ttl == 0) { | 733 | if (ttl == 0) { |
735 | sdata->u.sta.mshstats.dropped_frames_ttl++; | 734 | sdata->u.mesh.mshstats.dropped_frames_ttl++; |
736 | spin_unlock_bh(&mpath->state_lock); | 735 | spin_unlock_bh(&mpath->state_lock); |
737 | goto enddiscovery; | 736 | goto enddiscovery; |
738 | } | 737 | } |
@@ -743,11 +742,11 @@ void mesh_path_start_discovery(struct net_device *dev) | |||
743 | dst_flags = MP_F_RF; | 742 | dst_flags = MP_F_RF; |
744 | 743 | ||
745 | spin_unlock_bh(&mpath->state_lock); | 744 | spin_unlock_bh(&mpath->state_lock); |
746 | mesh_path_sel_frame_tx(MPATH_PREQ, 0, dev->dev_addr, | 745 | mesh_path_sel_frame_tx(MPATH_PREQ, 0, sdata->dev->dev_addr, |
747 | cpu_to_le32(ifsta->dsn), dst_flags, mpath->dst, | 746 | cpu_to_le32(ifmsh->dsn), dst_flags, mpath->dst, |
748 | cpu_to_le32(mpath->dsn), dev->broadcast, 0, | 747 | cpu_to_le32(mpath->dsn), sdata->dev->broadcast, 0, |
749 | ttl, cpu_to_le32(lifetime), 0, | 748 | ttl, cpu_to_le32(lifetime), 0, |
750 | cpu_to_le32(ifsta->preq_id++), dev); | 749 | cpu_to_le32(ifmsh->preq_id++), sdata); |
751 | mod_timer(&mpath->timer, jiffies + mpath->discovery_timeout); | 750 | mod_timer(&mpath->timer, jiffies + mpath->discovery_timeout); |
752 | 751 | ||
753 | enddiscovery: | 752 | enddiscovery: |
@@ -759,7 +758,7 @@ enddiscovery: | |||
759 | * ieee80211s_lookup_nexthop - put the appropriate next hop on a mesh frame | 758 | * ieee80211s_lookup_nexthop - put the appropriate next hop on a mesh frame |
760 | * | 759 | * |
761 | * @skb: 802.11 frame to be sent | 760 | * @skb: 802.11 frame to be sent |
762 | * @dev: network device the frame will be sent through | 761 | * @sdata: network subif the frame will be sent through |
763 | * @fwd_frame: true if this frame was originally from a different host | 762 | * @fwd_frame: true if this frame was originally from a different host |
764 | * | 763 | * |
765 | * Returns: 0 if the next hop was found. Nonzero otherwise. If no next hop is | 764 | * Returns: 0 if the next hop was found. Nonzero otherwise. If no next hop is |
@@ -767,9 +766,9 @@ enddiscovery: | |||
767 | * sent when the path is resolved. This means the caller must not free the skb | 766 | * sent when the path is resolved. This means the caller must not free the skb |
768 | * in this case. | 767 | * in this case. |
769 | */ | 768 | */ |
770 | int mesh_nexthop_lookup(struct sk_buff *skb, struct net_device *dev) | 769 | int mesh_nexthop_lookup(struct sk_buff *skb, |
770 | struct ieee80211_sub_if_data *sdata) | ||
771 | { | 771 | { |
772 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
773 | struct sk_buff *skb_to_free = NULL; | 772 | struct sk_buff *skb_to_free = NULL; |
774 | struct mesh_path *mpath; | 773 | struct mesh_path *mpath; |
775 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 774 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
@@ -777,14 +776,14 @@ int mesh_nexthop_lookup(struct sk_buff *skb, struct net_device *dev) | |||
777 | int err = 0; | 776 | int err = 0; |
778 | 777 | ||
779 | rcu_read_lock(); | 778 | rcu_read_lock(); |
780 | mpath = mesh_path_lookup(dst_addr, dev); | 779 | mpath = mesh_path_lookup(dst_addr, sdata); |
781 | 780 | ||
782 | if (!mpath) { | 781 | if (!mpath) { |
783 | mesh_path_add(dst_addr, dev); | 782 | mesh_path_add(dst_addr, sdata); |
784 | mpath = mesh_path_lookup(dst_addr, dev); | 783 | mpath = mesh_path_lookup(dst_addr, sdata); |
785 | if (!mpath) { | 784 | if (!mpath) { |
786 | dev_kfree_skb(skb); | 785 | dev_kfree_skb(skb); |
787 | sdata->u.sta.mshstats.dropped_frames_no_route++; | 786 | sdata->u.mesh.mshstats.dropped_frames_no_route++; |
788 | err = -ENOSPC; | 787 | err = -ENOSPC; |
789 | goto endlookup; | 788 | goto endlookup; |
790 | } | 789 | } |
@@ -792,14 +791,15 @@ int mesh_nexthop_lookup(struct sk_buff *skb, struct net_device *dev) | |||
792 | 791 | ||
793 | if (mpath->flags & MESH_PATH_ACTIVE) { | 792 | if (mpath->flags & MESH_PATH_ACTIVE) { |
794 | if (time_after(jiffies, mpath->exp_time - | 793 | if (time_after(jiffies, mpath->exp_time - |
795 | msecs_to_jiffies(sdata->u.sta.mshcfg.path_refresh_time)) | 794 | msecs_to_jiffies(sdata->u.mesh.mshcfg.path_refresh_time)) |
796 | && !memcmp(dev->dev_addr, hdr->addr4, ETH_ALEN) | 795 | && !memcmp(sdata->dev->dev_addr, hdr->addr4, |
796 | ETH_ALEN) | ||
797 | && !(mpath->flags & MESH_PATH_RESOLVING) | 797 | && !(mpath->flags & MESH_PATH_RESOLVING) |
798 | && !(mpath->flags & MESH_PATH_FIXED)) { | 798 | && !(mpath->flags & MESH_PATH_FIXED)) { |
799 | mesh_queue_preq(mpath, | 799 | mesh_queue_preq(mpath, |
800 | PREQ_Q_F_START | PREQ_Q_F_REFRESH); | 800 | PREQ_Q_F_START | PREQ_Q_F_REFRESH); |
801 | } | 801 | } |
802 | memcpy(hdr->addr1, mpath->next_hop->addr, | 802 | memcpy(hdr->addr1, mpath->next_hop->sta.addr, |
803 | ETH_ALEN); | 803 | ETH_ALEN); |
804 | } else { | 804 | } else { |
805 | if (!(mpath->flags & MESH_PATH_RESOLVING)) { | 805 | if (!(mpath->flags & MESH_PATH_RESOLVING)) { |
@@ -815,7 +815,7 @@ int mesh_nexthop_lookup(struct sk_buff *skb, struct net_device *dev) | |||
815 | 815 | ||
816 | skb_queue_tail(&mpath->frame_queue, skb); | 816 | skb_queue_tail(&mpath->frame_queue, skb); |
817 | if (skb_to_free) | 817 | if (skb_to_free) |
818 | mesh_path_discard_frame(skb_to_free, dev); | 818 | mesh_path_discard_frame(skb_to_free, sdata); |
819 | err = -ENOENT; | 819 | err = -ENOENT; |
820 | } | 820 | } |
821 | 821 | ||
@@ -835,7 +835,7 @@ void mesh_path_timer(unsigned long data) | |||
835 | if (!mpath) | 835 | if (!mpath) |
836 | goto endmpathtimer; | 836 | goto endmpathtimer; |
837 | spin_lock_bh(&mpath->state_lock); | 837 | spin_lock_bh(&mpath->state_lock); |
838 | sdata = IEEE80211_DEV_TO_SUB_IF(mpath->dev); | 838 | sdata = mpath->sdata; |
839 | if (mpath->flags & MESH_PATH_RESOLVED || | 839 | if (mpath->flags & MESH_PATH_RESOLVED || |
840 | (!(mpath->flags & MESH_PATH_RESOLVING))) | 840 | (!(mpath->flags & MESH_PATH_RESOLVING))) |
841 | mpath->flags &= ~(MESH_PATH_RESOLVING | MESH_PATH_RESOLVED); | 841 | mpath->flags &= ~(MESH_PATH_RESOLVING | MESH_PATH_RESOLVED); |