PageRenderTime 27ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/openwrt/package/madwifi/patches/357-bgscan_thresh.patch

https://github.com/bifferos/bb
Patch | 160 lines | 148 code | 12 blank | 0 comment | 0 complexity | 0d42765006fc41809c239ffbd1d4ecee MD5 | raw file
  1. Add an optional background scanning threshold triggered by low rssi
  2. (useful for passing updated scan results to the supplicant ahead of
  3. time, before losing connectivity entirely)
  4. Signed-off-by: Felix Fietkau <nbd@openwrt.org>
  5. --- a/net80211/ieee80211_ioctl.h
  6. +++ b/net80211/ieee80211_ioctl.h
  7. @@ -646,6 +646,7 @@ enum {
  8. IEEE80211_PARAM_MINRATE = 76, /* Minimum rate (by table index) */
  9. IEEE80211_PARAM_PROTMODE_RSSI = 77, /* RSSI Threshold for enabling protection mode */
  10. IEEE80211_PARAM_PROTMODE_TIMEOUT = 78, /* Timeout for expiring protection mode */
  11. + IEEE80211_PARAM_BGSCAN_THRESH = 79, /* bg scan rssi threshold */
  12. };
  13. #define SIOCG80211STATS (SIOCDEVPRIVATE+2)
  14. --- a/net80211/ieee80211_var.h
  15. +++ b/net80211/ieee80211_var.h
  16. @@ -92,6 +92,8 @@
  17. #define IEEE80211_BGSCAN_IDLE_MIN 100 /* min idle time (ms) */
  18. #define IEEE80211_BGSCAN_IDLE_DEFAULT 250 /* default idle time (ms) */
  19. +#define IEEE80211_BGSCAN_TRIGGER_INTVL 20 /* min trigger interval for thresh based bgscan (secs) */
  20. +
  21. #define IEEE80211_COVERAGE_CLASS_MAX 31 /* max coverage class */
  22. #define IEEE80211_REGCLASSIDS_MAX 10 /* max regclass id list */
  23. @@ -219,6 +221,10 @@ struct ieee80211vap {
  24. u_int8_t iv_nickname[IEEE80211_NWID_LEN];
  25. u_int iv_bgscanidle; /* bg scan idle threshold */
  26. u_int iv_bgscanintvl; /* bg scan min interval */
  27. + u_int iv_bgscanthr; /* bg scan rssi threshold */
  28. + u_int iv_bgscantrintvl; /* bg scan trigger interval */
  29. + unsigned long iv_bgscanthr_next; /* last trigger for bgscan */
  30. + unsigned long iv_lastconnect; /* time of last connect attempt */
  31. u_int iv_scanvalid; /* scan cache valid threshold */
  32. struct ieee80211_roam iv_roam; /* sta-mode roaming state */
  33. @@ -608,6 +614,7 @@ MALLOC_DECLARE(M_80211_VAP);
  34. #define IEEE80211_FEXT_SWBMISS 0x00000400 /* CONF: use software beacon timer */
  35. #define IEEE80211_FEXT_DROPUNENC_EAPOL 0x00000800 /* CONF: drop unencrypted eapol frames */
  36. #define IEEE80211_FEXT_APPIE_UPDATE 0x00001000 /* STATE: beacon APP IE updated */
  37. +#define IEEE80211_FEXT_BGSCAN_THR 0x00002000 /* bgscan due to low rssi */
  38. #define IEEE80211_COM_UAPSD_ENABLE(_ic) ((_ic)->ic_flags_ext |= IEEE80211_FEXT_UAPSD)
  39. #define IEEE80211_COM_UAPSD_DISABLE(_ic) ((_ic)->ic_flags_ext &= ~IEEE80211_FEXT_UAPSD)
  40. --- a/net80211/ieee80211_wireless.c
  41. +++ b/net80211/ieee80211_wireless.c
  42. @@ -2744,6 +2744,9 @@ ieee80211_ioctl_setparam(struct net_devi
  43. else
  44. retv = EINVAL;
  45. break;
  46. + case IEEE80211_PARAM_BGSCAN_THRESH:
  47. + vap->iv_bgscanthr = value;
  48. + break;
  49. case IEEE80211_PARAM_MCAST_RATE:
  50. /* units are in KILObits per second */
  51. if (value >= 256 && value <= 54000)
  52. @@ -3144,6 +3147,9 @@ ieee80211_ioctl_getparam(struct net_devi
  53. case IEEE80211_PARAM_BGSCAN_INTERVAL:
  54. param[0] = vap->iv_bgscanintvl / HZ; /* seconds */
  55. break;
  56. + case IEEE80211_PARAM_BGSCAN_THRESH:
  57. + param[0] = vap->iv_bgscanthr; /* rssi */
  58. + break;
  59. case IEEE80211_PARAM_MCAST_RATE:
  60. param[0] = vap->iv_mcast_rate; /* seconds */
  61. break;
  62. @@ -5666,6 +5672,10 @@ static const struct iw_priv_args ieee802
  63. IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "bgscanintvl" },
  64. { IEEE80211_PARAM_BGSCAN_INTERVAL,
  65. 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_bgscanintvl" },
  66. + { IEEE80211_PARAM_BGSCAN_THRESH,
  67. + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "bgscanthr" },
  68. + { IEEE80211_PARAM_BGSCAN_THRESH,
  69. + 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_bgscanthr" },
  70. { IEEE80211_PARAM_MCAST_RATE,
  71. IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "mcast_rate" },
  72. { IEEE80211_PARAM_MCAST_RATE,
  73. --- a/net80211/ieee80211_input.c
  74. +++ b/net80211/ieee80211_input.c
  75. @@ -3013,8 +3013,10 @@ contbgscan(struct ieee80211vap *vap)
  76. {
  77. struct ieee80211com *ic = vap->iv_ic;
  78. + vap->iv_bgscantrintvl = (vap->iv_bgscantrintvl + 1) % 4;
  79. return ((ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN) &&
  80. - time_after(jiffies, ic->ic_lastdata + vap->iv_bgscanidle));
  81. + (((ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN_THR) && !vap->iv_bgscantrintvl) ||
  82. + time_after(jiffies, ic->ic_lastdata + vap->iv_bgscanidle)));
  83. }
  84. static __inline int
  85. @@ -3258,6 +3260,25 @@ ieee80211_recv_mgmt(struct ieee80211vap
  86. /* record tsf of last beacon */
  87. memcpy(ni->ni_tstamp.data, scan.tstamp,
  88. sizeof(ni->ni_tstamp));
  89. +
  90. + /* When rssi is low, start doing bgscans more frequently to allow
  91. + * the supplicant to make a better switching decision */
  92. + if (!(ic->ic_flags & IEEE80211_F_SCAN) && (rssi < vap->iv_bgscanthr) &&
  93. + (!vap->iv_bgscanthr_next ||
  94. + !time_before(jiffies, vap->iv_bgscanthr_next)) &&
  95. + (vap->iv_state == IEEE80211_S_RUN) &&
  96. + time_after(jiffies, vap->iv_lastconnect +
  97. + msecs_to_jiffies(IEEE80211_BGSCAN_INTVAL_MIN * 1000))) {
  98. + int ret;
  99. +
  100. + ic->ic_lastdata = 0;
  101. + ic->ic_lastscan = 0;
  102. + ic->ic_flags_ext |= IEEE80211_FEXT_BGSCAN_THR;
  103. + ret = ieee80211_bg_scan(vap);
  104. + if (ret)
  105. + vap->iv_bgscanthr_next = jiffies + msecs_to_jiffies(IEEE80211_BGSCAN_TRIGGER_INTVL * 1000);
  106. + }
  107. +
  108. if (ni->ni_intval != scan.bintval) {
  109. IEEE80211_NOTE(vap, IEEE80211_MSG_ASSOC, ni,
  110. "beacon interval divergence: "
  111. --- a/net80211/ieee80211_scan.c
  112. +++ b/net80211/ieee80211_scan.c
  113. @@ -616,6 +616,7 @@ ieee80211_cancel_scan(struct ieee80211va
  114. /* clear bg scan NOPICK and mark cancel request */
  115. ss->ss_flags &= ~IEEE80211_SCAN_NOPICK;
  116. + ic->ic_flags_ext &= ~IEEE80211_FEXT_BGSCAN_THR;
  117. SCAN_PRIVATE(ss)->ss_iflags |= ISCAN_CANCEL;
  118. ss->ss_ops->scan_cancel(ss, vap);
  119. /* force it to fire asap */
  120. @@ -782,7 +783,7 @@ again:
  121. ieee80211_sta_pwrsave(vap, 0);
  122. if (ss->ss_next >= ss->ss_last) {
  123. ieee80211_notify_scan_done(vap);
  124. - ic->ic_flags_ext &= ~IEEE80211_FEXT_BGSCAN;
  125. + ic->ic_flags_ext &= ~(IEEE80211_FEXT_BGSCAN|IEEE80211_FEXT_BGSCAN_THR);
  126. }
  127. }
  128. SCAN_PRIVATE(ss)->ss_iflags &= ~ISCAN_CANCEL;
  129. --- a/net80211/ieee80211_proto.c
  130. +++ b/net80211/ieee80211_proto.c
  131. @@ -1450,6 +1450,7 @@ __ieee80211_newstate(struct ieee80211vap
  132. }
  133. break;
  134. case IEEE80211_S_AUTH:
  135. + vap->iv_lastconnect = jiffies;
  136. /* auth frames are possible between IBSS nodes,
  137. * see 802.11-1999, chapter 5.7.6 */
  138. KASSERT(vap->iv_opmode == IEEE80211_M_STA ||
  139. --- a/net80211/ieee80211_output.c
  140. +++ b/net80211/ieee80211_output.c
  141. @@ -238,7 +238,8 @@ ieee80211_hardstart(struct sk_buff *skb,
  142. }
  143. /* Cancel any running BG scan */
  144. - ieee80211_cancel_scan(vap);
  145. + if (!(ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN_THR) && (vap->iv_state == IEEE80211_S_RUN))
  146. + ieee80211_cancel_scan(vap);
  147. /*
  148. * Find the node for the destination so we can do