diff options
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_acx.c | 71 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_acx.h | 56 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_boot.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_conf.h | 103 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_event.c | 24 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_event.h | 8 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_init.c | 5 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_main.c | 52 |
9 files changed, 228 insertions, 97 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h index 789460074670..75887e74205b 100644 --- a/drivers/net/wireless/wl12xx/wl1271.h +++ b/drivers/net/wireless/wl12xx/wl1271.h | |||
@@ -473,6 +473,9 @@ struct wl1271 { | |||
473 | /* in dBm */ | 473 | /* in dBm */ |
474 | int power_level; | 474 | int power_level; |
475 | 475 | ||
476 | int rssi_thold; | ||
477 | int last_rssi_event; | ||
478 | |||
476 | struct wl1271_stats stats; | 479 | struct wl1271_stats stats; |
477 | struct wl1271_debugfs debugfs; | 480 | struct wl1271_debugfs debugfs; |
478 | 481 | ||
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.c b/drivers/net/wireless/wl12xx/wl1271_acx.c index 621c94691e7e..1a6b2ec1db58 100644 --- a/drivers/net/wireless/wl12xx/wl1271_acx.c +++ b/drivers/net/wireless/wl12xx/wl1271_acx.c | |||
@@ -1165,6 +1165,7 @@ out: | |||
1165 | kfree(acx); | 1165 | kfree(acx); |
1166 | return ret; | 1166 | return ret; |
1167 | } | 1167 | } |
1168 | |||
1168 | int wl1271_acx_keep_alive_config(struct wl1271 *wl, u8 index, u8 tpl_valid) | 1169 | int wl1271_acx_keep_alive_config(struct wl1271 *wl, u8 index, u8 tpl_valid) |
1169 | { | 1170 | { |
1170 | struct wl1271_acx_keep_alive_config *acx = NULL; | 1171 | struct wl1271_acx_keep_alive_config *acx = NULL; |
@@ -1194,3 +1195,73 @@ out: | |||
1194 | kfree(acx); | 1195 | kfree(acx); |
1195 | return ret; | 1196 | return ret; |
1196 | } | 1197 | } |
1198 | |||
1199 | int wl1271_acx_rssi_snr_trigger(struct wl1271 *wl, bool enable, | ||
1200 | s16 thold, u8 hyst) | ||
1201 | { | ||
1202 | struct wl1271_acx_rssi_snr_trigger *acx = NULL; | ||
1203 | int ret = 0; | ||
1204 | |||
1205 | wl1271_debug(DEBUG_ACX, "acx rssi snr trigger"); | ||
1206 | |||
1207 | acx = kzalloc(sizeof(*acx), GFP_KERNEL); | ||
1208 | if (!acx) { | ||
1209 | ret = -ENOMEM; | ||
1210 | goto out; | ||
1211 | } | ||
1212 | |||
1213 | wl->last_rssi_event = -1; | ||
1214 | |||
1215 | acx->pacing = cpu_to_le16(wl->conf.roam_trigger.trigger_pacing); | ||
1216 | acx->metric = WL1271_ACX_TRIG_METRIC_RSSI_BEACON; | ||
1217 | acx->type = WL1271_ACX_TRIG_TYPE_EDGE; | ||
1218 | if (enable) | ||
1219 | acx->enable = WL1271_ACX_TRIG_ENABLE; | ||
1220 | else | ||
1221 | acx->enable = WL1271_ACX_TRIG_DISABLE; | ||
1222 | |||
1223 | acx->index = WL1271_ACX_TRIG_IDX_RSSI; | ||
1224 | acx->dir = WL1271_ACX_TRIG_DIR_BIDIR; | ||
1225 | acx->threshold = cpu_to_le16(thold); | ||
1226 | acx->hysteresis = hyst; | ||
1227 | |||
1228 | ret = wl1271_cmd_configure(wl, ACX_RSSI_SNR_TRIGGER, acx, sizeof(*acx)); | ||
1229 | if (ret < 0) { | ||
1230 | wl1271_warning("acx rssi snr trigger setting failed: %d", ret); | ||
1231 | goto out; | ||
1232 | } | ||
1233 | |||
1234 | out: | ||
1235 | kfree(acx); | ||
1236 | return ret; | ||
1237 | } | ||
1238 | |||
1239 | int wl1271_acx_rssi_snr_avg_weights(struct wl1271 *wl) | ||
1240 | { | ||
1241 | struct wl1271_acx_rssi_snr_avg_weights *acx = NULL; | ||
1242 | struct conf_roam_trigger_settings *c = &wl->conf.roam_trigger; | ||
1243 | int ret = 0; | ||
1244 | |||
1245 | wl1271_debug(DEBUG_ACX, "acx rssi snr avg weights"); | ||
1246 | |||
1247 | acx = kzalloc(sizeof(*acx), GFP_KERNEL); | ||
1248 | if (!acx) { | ||
1249 | ret = -ENOMEM; | ||
1250 | goto out; | ||
1251 | } | ||
1252 | |||
1253 | acx->rssi_beacon = c->avg_weight_rssi_beacon; | ||
1254 | acx->rssi_data = c->avg_weight_rssi_data; | ||
1255 | acx->snr_beacon = c->avg_weight_snr_beacon; | ||
1256 | acx->snr_data = c->avg_weight_snr_data; | ||
1257 | |||
1258 | ret = wl1271_cmd_configure(wl, ACX_RSSI_SNR_WEIGHTS, acx, sizeof(*acx)); | ||
1259 | if (ret < 0) { | ||
1260 | wl1271_warning("acx rssi snr trigger weights failed: %d", ret); | ||
1261 | goto out; | ||
1262 | } | ||
1263 | |||
1264 | out: | ||
1265 | kfree(acx); | ||
1266 | return ret; | ||
1267 | } | ||
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.h b/drivers/net/wireless/wl12xx/wl1271_acx.h index 15cc56192de9..420e7e2fc021 100644 --- a/drivers/net/wireless/wl12xx/wl1271_acx.h +++ b/drivers/net/wireless/wl12xx/wl1271_acx.h | |||
@@ -943,6 +943,57 @@ struct wl1271_acx_keep_alive_config { | |||
943 | } __attribute__ ((packed)); | 943 | } __attribute__ ((packed)); |
944 | 944 | ||
945 | enum { | 945 | enum { |
946 | WL1271_ACX_TRIG_TYPE_LEVEL = 0, | ||
947 | WL1271_ACX_TRIG_TYPE_EDGE, | ||
948 | }; | ||
949 | |||
950 | enum { | ||
951 | WL1271_ACX_TRIG_DIR_LOW = 0, | ||
952 | WL1271_ACX_TRIG_DIR_HIGH, | ||
953 | WL1271_ACX_TRIG_DIR_BIDIR, | ||
954 | }; | ||
955 | |||
956 | enum { | ||
957 | WL1271_ACX_TRIG_ENABLE = 1, | ||
958 | WL1271_ACX_TRIG_DISABLE, | ||
959 | }; | ||
960 | |||
961 | enum { | ||
962 | WL1271_ACX_TRIG_METRIC_RSSI_BEACON = 0, | ||
963 | WL1271_ACX_TRIG_METRIC_RSSI_DATA, | ||
964 | WL1271_ACX_TRIG_METRIC_SNR_BEACON, | ||
965 | WL1271_ACX_TRIG_METRIC_SNR_DATA, | ||
966 | }; | ||
967 | |||
968 | enum { | ||
969 | WL1271_ACX_TRIG_IDX_RSSI = 0, | ||
970 | WL1271_ACX_TRIG_COUNT = 8, | ||
971 | }; | ||
972 | |||
973 | struct wl1271_acx_rssi_snr_trigger { | ||
974 | struct acx_header header; | ||
975 | |||
976 | __le16 threshold; | ||
977 | __le16 pacing; /* 0 - 60000 ms */ | ||
978 | u8 metric; | ||
979 | u8 type; | ||
980 | u8 dir; | ||
981 | u8 hysteresis; | ||
982 | u8 index; | ||
983 | u8 enable; | ||
984 | u8 padding[2]; | ||
985 | }; | ||
986 | |||
987 | struct wl1271_acx_rssi_snr_avg_weights { | ||
988 | struct acx_header header; | ||
989 | |||
990 | u8 rssi_beacon; | ||
991 | u8 rssi_data; | ||
992 | u8 snr_beacon; | ||
993 | u8 snr_data; | ||
994 | }; | ||
995 | |||
996 | enum { | ||
946 | ACX_WAKE_UP_CONDITIONS = 0x0002, | 997 | ACX_WAKE_UP_CONDITIONS = 0x0002, |
947 | ACX_MEM_CFG = 0x0003, | 998 | ACX_MEM_CFG = 0x0003, |
948 | ACX_SLOT = 0x0004, | 999 | ACX_SLOT = 0x0004, |
@@ -990,7 +1041,7 @@ enum { | |||
990 | ACX_FRAG_CFG = 0x004F, | 1041 | ACX_FRAG_CFG = 0x004F, |
991 | ACX_BET_ENABLE = 0x0050, | 1042 | ACX_BET_ENABLE = 0x0050, |
992 | ACX_RSSI_SNR_TRIGGER = 0x0051, | 1043 | ACX_RSSI_SNR_TRIGGER = 0x0051, |
993 | ACX_RSSI_SNR_WEIGHTS = 0x0051, | 1044 | ACX_RSSI_SNR_WEIGHTS = 0x0052, |
994 | ACX_KEEP_ALIVE_MODE = 0x0053, | 1045 | ACX_KEEP_ALIVE_MODE = 0x0053, |
995 | ACX_SET_KEEP_ALIVE_CONFIG = 0x0054, | 1046 | ACX_SET_KEEP_ALIVE_CONFIG = 0x0054, |
996 | ACX_BA_SESSION_RESPONDER_POLICY = 0x0055, | 1047 | ACX_BA_SESSION_RESPONDER_POLICY = 0x0055, |
@@ -1060,5 +1111,8 @@ int wl1271_acx_arp_ip_filter(struct wl1271 *wl, bool enable, u8 *address, | |||
1060 | int wl1271_acx_pm_config(struct wl1271 *wl); | 1111 | int wl1271_acx_pm_config(struct wl1271 *wl); |
1061 | int wl1271_acx_keep_alive_mode(struct wl1271 *wl, bool enable); | 1112 | int wl1271_acx_keep_alive_mode(struct wl1271 *wl, bool enable); |
1062 | int wl1271_acx_keep_alive_config(struct wl1271 *wl, u8 index, u8 tpl_valid); | 1113 | int wl1271_acx_keep_alive_config(struct wl1271 *wl, u8 index, u8 tpl_valid); |
1114 | int wl1271_acx_rssi_snr_trigger(struct wl1271 *wl, bool enable, | ||
1115 | s16 thold, u8 hyst); | ||
1116 | int wl1271_acx_rssi_snr_avg_weights(struct wl1271 *wl); | ||
1063 | 1117 | ||
1064 | #endif /* __WL1271_ACX_H__ */ | 1118 | #endif /* __WL1271_ACX_H__ */ |
diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.c b/drivers/net/wireless/wl12xx/wl1271_boot.c index 7acef88df1fe..f16d15bd5643 100644 --- a/drivers/net/wireless/wl12xx/wl1271_boot.c +++ b/drivers/net/wireless/wl12xx/wl1271_boot.c | |||
@@ -412,7 +412,8 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl) | |||
412 | SCAN_COMPLETE_EVENT_ID | | 412 | SCAN_COMPLETE_EVENT_ID | |
413 | PS_REPORT_EVENT_ID | | 413 | PS_REPORT_EVENT_ID | |
414 | JOIN_EVENT_COMPLETE_ID | | 414 | JOIN_EVENT_COMPLETE_ID | |
415 | DISCONNECT_EVENT_COMPLETE_ID; | 415 | DISCONNECT_EVENT_COMPLETE_ID | |
416 | RSSI_SNR_TRIGGER_0_EVENT_ID; | ||
416 | 417 | ||
417 | ret = wl1271_event_unmask(wl); | 418 | ret = wl1271_event_unmask(wl); |
418 | if (ret < 0) { | 419 | if (ret < 0) { |
diff --git a/drivers/net/wireless/wl12xx/wl1271_conf.h b/drivers/net/wireless/wl12xx/wl1271_conf.h index d76ae03762a3..c44307c4bcf8 100644 --- a/drivers/net/wireless/wl12xx/wl1271_conf.h +++ b/drivers/net/wireless/wl12xx/wl1271_conf.h | |||
@@ -756,65 +756,6 @@ enum { | |||
756 | CONF_TRIG_EVENT_DIR_BIDIR | 756 | CONF_TRIG_EVENT_DIR_BIDIR |
757 | }; | 757 | }; |
758 | 758 | ||
759 | |||
760 | struct conf_sig_trigger { | ||
761 | /* | ||
762 | * The RSSI / SNR threshold value. | ||
763 | * | ||
764 | * FIXME: what is the range? | ||
765 | */ | ||
766 | s16 threshold; | ||
767 | |||
768 | /* | ||
769 | * Minimum delay between two trigger events for this trigger in ms. | ||
770 | * | ||
771 | * Range: 0 - 60000 | ||
772 | */ | ||
773 | u16 pacing; | ||
774 | |||
775 | /* | ||
776 | * The measurement data source for this trigger. | ||
777 | * | ||
778 | * Range: CONF_TRIG_METRIC_* | ||
779 | */ | ||
780 | u8 metric; | ||
781 | |||
782 | /* | ||
783 | * The trigger type of this trigger. | ||
784 | * | ||
785 | * Range: CONF_TRIG_EVENT_TYPE_* | ||
786 | */ | ||
787 | u8 type; | ||
788 | |||
789 | /* | ||
790 | * The direction of the trigger. | ||
791 | * | ||
792 | * Range: CONF_TRIG_EVENT_DIR_* | ||
793 | */ | ||
794 | u8 direction; | ||
795 | |||
796 | /* | ||
797 | * Hysteresis range of the trigger around the threshold (in dB) | ||
798 | * | ||
799 | * Range: u8 | ||
800 | */ | ||
801 | u8 hysteresis; | ||
802 | |||
803 | /* | ||
804 | * Index of the trigger rule. | ||
805 | * | ||
806 | * Range: 0 - CONF_MAX_RSSI_SNR_TRIGGERS-1 | ||
807 | */ | ||
808 | u8 index; | ||
809 | |||
810 | /* | ||
811 | * Enable / disable this rule (to use for clearing rules.) | ||
812 | * | ||
813 | * Range: 1 - Enabled, 2 - Not enabled | ||
814 | */ | ||
815 | u8 enable; | ||
816 | }; | ||
817 | |||
818 | struct conf_sig_weights { | 759 | struct conf_sig_weights { |
819 | 760 | ||
820 | /* | 761 | /* |
@@ -933,12 +874,6 @@ struct conf_conn_settings { | |||
933 | u8 ps_poll_threshold; | 874 | u8 ps_poll_threshold; |
934 | 875 | ||
935 | /* | 876 | /* |
936 | * Configuration of signal (rssi/snr) triggers. | ||
937 | */ | ||
938 | u8 sig_trigger_count; | ||
939 | struct conf_sig_trigger sig_trigger[CONF_MAX_RSSI_SNR_TRIGGERS]; | ||
940 | |||
941 | /* | ||
942 | * Configuration of signal average weights. | 877 | * Configuration of signal average weights. |
943 | */ | 878 | */ |
944 | struct conf_sig_weights sig_weights; | 879 | struct conf_sig_weights sig_weights; |
@@ -1045,6 +980,43 @@ struct conf_pm_config_settings { | |||
1045 | bool host_fast_wakeup_support; | 980 | bool host_fast_wakeup_support; |
1046 | }; | 981 | }; |
1047 | 982 | ||
983 | struct conf_roam_trigger_settings { | ||
984 | /* | ||
985 | * The minimum interval between two trigger events. | ||
986 | * | ||
987 | * Range: 0 - 60000 ms | ||
988 | */ | ||
989 | u16 trigger_pacing; | ||
990 | |||
991 | /* | ||
992 | * The weight for rssi/beacon average calculation | ||
993 | * | ||
994 | * Range: 0 - 255 | ||
995 | */ | ||
996 | u8 avg_weight_rssi_beacon; | ||
997 | |||
998 | /* | ||
999 | * The weight for rssi/data frame average calculation | ||
1000 | * | ||
1001 | * Range: 0 - 255 | ||
1002 | */ | ||
1003 | u8 avg_weight_rssi_data; | ||
1004 | |||
1005 | /* | ||
1006 | * The weight for snr/beacon average calculation | ||
1007 | * | ||
1008 | * Range: 0 - 255 | ||
1009 | */ | ||
1010 | u8 avg_weight_snr_beacon; | ||
1011 | |||
1012 | /* | ||
1013 | * The weight for snr/data frame average calculation | ||
1014 | * | ||
1015 | * Range: 0 - 255 | ||
1016 | */ | ||
1017 | u8 avg_weight_snr_data; | ||
1018 | }; | ||
1019 | |||
1048 | struct conf_drv_settings { | 1020 | struct conf_drv_settings { |
1049 | struct conf_sg_settings sg; | 1021 | struct conf_sg_settings sg; |
1050 | struct conf_rx_settings rx; | 1022 | struct conf_rx_settings rx; |
@@ -1053,6 +1025,7 @@ struct conf_drv_settings { | |||
1053 | struct conf_init_settings init; | 1025 | struct conf_init_settings init; |
1054 | struct conf_itrim_settings itrim; | 1026 | struct conf_itrim_settings itrim; |
1055 | struct conf_pm_config_settings pm_config; | 1027 | struct conf_pm_config_settings pm_config; |
1028 | struct conf_roam_trigger_settings roam_trigger; | ||
1056 | }; | 1029 | }; |
1057 | 1030 | ||
1058 | #endif | 1031 | #endif |
diff --git a/drivers/net/wireless/wl12xx/wl1271_event.c b/drivers/net/wireless/wl12xx/wl1271_event.c index daacf176cf09..cf37aa6eb137 100644 --- a/drivers/net/wireless/wl12xx/wl1271_event.c +++ b/drivers/net/wireless/wl12xx/wl1271_event.c | |||
@@ -125,6 +125,24 @@ static int wl1271_event_ps_report(struct wl1271 *wl, | |||
125 | return ret; | 125 | return ret; |
126 | } | 126 | } |
127 | 127 | ||
128 | static void wl1271_event_rssi_trigger(struct wl1271 *wl, | ||
129 | struct event_mailbox *mbox) | ||
130 | { | ||
131 | enum nl80211_cqm_rssi_threshold_event event; | ||
132 | s8 metric = mbox->rssi_snr_trigger_metric[0]; | ||
133 | |||
134 | wl1271_debug(DEBUG_EVENT, "RSSI trigger metric: %d", metric); | ||
135 | |||
136 | if (metric <= wl->rssi_thold) | ||
137 | event = NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW; | ||
138 | else | ||
139 | event = NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH; | ||
140 | |||
141 | if (event != wl->last_rssi_event) | ||
142 | ieee80211_cqm_rssi_notify(wl->vif, event, GFP_KERNEL); | ||
143 | wl->last_rssi_event = event; | ||
144 | } | ||
145 | |||
128 | static void wl1271_event_mbox_dump(struct event_mailbox *mbox) | 146 | static void wl1271_event_mbox_dump(struct event_mailbox *mbox) |
129 | { | 147 | { |
130 | wl1271_debug(DEBUG_EVENT, "MBOX DUMP:"); | 148 | wl1271_debug(DEBUG_EVENT, "MBOX DUMP:"); |
@@ -173,6 +191,12 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox) | |||
173 | return ret; | 191 | return ret; |
174 | } | 192 | } |
175 | 193 | ||
194 | if (vector & RSSI_SNR_TRIGGER_0_EVENT_ID) { | ||
195 | wl1271_debug(DEBUG_EVENT, "RSSI_SNR_TRIGGER_0_EVENT"); | ||
196 | if (wl->vif) | ||
197 | wl1271_event_rssi_trigger(wl, mbox); | ||
198 | } | ||
199 | |||
176 | if (wl->vif && beacon_loss) | 200 | if (wl->vif && beacon_loss) |
177 | ieee80211_connection_loss(wl->vif); | 201 | ieee80211_connection_loss(wl->vif); |
178 | 202 | ||
diff --git a/drivers/net/wireless/wl12xx/wl1271_event.h b/drivers/net/wireless/wl12xx/wl1271_event.h index 278f9206aa56..58371008f270 100644 --- a/drivers/net/wireless/wl12xx/wl1271_event.h +++ b/drivers/net/wireless/wl12xx/wl1271_event.h | |||
@@ -38,6 +38,14 @@ | |||
38 | */ | 38 | */ |
39 | 39 | ||
40 | enum { | 40 | enum { |
41 | RSSI_SNR_TRIGGER_0_EVENT_ID = BIT(0), | ||
42 | RSSI_SNR_TRIGGER_1_EVENT_ID = BIT(1), | ||
43 | RSSI_SNR_TRIGGER_2_EVENT_ID = BIT(2), | ||
44 | RSSI_SNR_TRIGGER_3_EVENT_ID = BIT(3), | ||
45 | RSSI_SNR_TRIGGER_4_EVENT_ID = BIT(4), | ||
46 | RSSI_SNR_TRIGGER_5_EVENT_ID = BIT(5), | ||
47 | RSSI_SNR_TRIGGER_6_EVENT_ID = BIT(6), | ||
48 | RSSI_SNR_TRIGGER_7_EVENT_ID = BIT(7), | ||
41 | MEASUREMENT_START_EVENT_ID = BIT(8), | 49 | MEASUREMENT_START_EVENT_ID = BIT(8), |
42 | MEASUREMENT_COMPLETE_EVENT_ID = BIT(9), | 50 | MEASUREMENT_COMPLETE_EVENT_ID = BIT(9), |
43 | SCAN_COMPLETE_EVENT_ID = BIT(10), | 51 | SCAN_COMPLETE_EVENT_ID = BIT(10), |
diff --git a/drivers/net/wireless/wl12xx/wl1271_init.c b/drivers/net/wireless/wl12xx/wl1271_init.c index 9ab336829044..b880382cf15d 100644 --- a/drivers/net/wireless/wl12xx/wl1271_init.c +++ b/drivers/net/wireless/wl12xx/wl1271_init.c | |||
@@ -352,6 +352,11 @@ int wl1271_hw_init(struct wl1271 *wl) | |||
352 | if (ret < 0) | 352 | if (ret < 0) |
353 | goto out_free_memmap; | 353 | goto out_free_memmap; |
354 | 354 | ||
355 | /* Configure rssi/snr averaging weights */ | ||
356 | ret = wl1271_acx_rssi_snr_avg_weights(wl); | ||
357 | if (ret < 0) | ||
358 | goto out_free_memmap; | ||
359 | |||
355 | return 0; | 360 | return 0; |
356 | 361 | ||
357 | out_free_memmap: | 362 | out_free_memmap: |
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index 551714164ff5..283d5dade1ae 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c | |||
@@ -234,35 +234,6 @@ static struct conf_drv_settings default_conf = { | |||
234 | .broadcast_timeout = 20000, | 234 | .broadcast_timeout = 20000, |
235 | .rx_broadcast_in_ps = 1, | 235 | .rx_broadcast_in_ps = 1, |
236 | .ps_poll_threshold = 20, | 236 | .ps_poll_threshold = 20, |
237 | .sig_trigger_count = 2, | ||
238 | .sig_trigger = { | ||
239 | [0] = { | ||
240 | .threshold = -75, | ||
241 | .pacing = 500, | ||
242 | .metric = CONF_TRIG_METRIC_RSSI_BEACON, | ||
243 | .type = CONF_TRIG_EVENT_TYPE_EDGE, | ||
244 | .direction = CONF_TRIG_EVENT_DIR_LOW, | ||
245 | .hysteresis = 2, | ||
246 | .index = 0, | ||
247 | .enable = 1 | ||
248 | }, | ||
249 | [1] = { | ||
250 | .threshold = -75, | ||
251 | .pacing = 500, | ||
252 | .metric = CONF_TRIG_METRIC_RSSI_BEACON, | ||
253 | .type = CONF_TRIG_EVENT_TYPE_EDGE, | ||
254 | .direction = CONF_TRIG_EVENT_DIR_HIGH, | ||
255 | .hysteresis = 2, | ||
256 | .index = 1, | ||
257 | .enable = 1 | ||
258 | } | ||
259 | }, | ||
260 | .sig_weights = { | ||
261 | .rssi_bcn_avg_weight = 10, | ||
262 | .rssi_pkt_avg_weight = 10, | ||
263 | .snr_bcn_avg_weight = 10, | ||
264 | .snr_pkt_avg_weight = 10 | ||
265 | }, | ||
266 | .bet_enable = CONF_BET_MODE_ENABLE, | 237 | .bet_enable = CONF_BET_MODE_ENABLE, |
267 | .bet_max_consecutive = 10, | 238 | .bet_max_consecutive = 10, |
268 | .psm_entry_retries = 3, | 239 | .psm_entry_retries = 3, |
@@ -281,6 +252,14 @@ static struct conf_drv_settings default_conf = { | |||
281 | .pm_config = { | 252 | .pm_config = { |
282 | .host_clk_settling_time = 5000, | 253 | .host_clk_settling_time = 5000, |
283 | .host_fast_wakeup_support = false | 254 | .host_fast_wakeup_support = false |
255 | }, | ||
256 | .roam_trigger = { | ||
257 | /* FIXME: due to firmware bug, must use value 1 for now */ | ||
258 | .trigger_pacing = 1, | ||
259 | .avg_weight_rssi_beacon = 20, | ||
260 | .avg_weight_rssi_data = 10, | ||
261 | .avg_weight_snr_beacon = 20, | ||
262 | .avg_weight_snr_data = 10 | ||
284 | } | 263 | } |
285 | }; | 264 | }; |
286 | 265 | ||
@@ -1703,6 +1682,18 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, | |||
1703 | do_join = true; | 1682 | do_join = true; |
1704 | } | 1683 | } |
1705 | 1684 | ||
1685 | if (changed & BSS_CHANGED_CQM) { | ||
1686 | bool enable = false; | ||
1687 | if (bss_conf->cqm_rssi_thold) | ||
1688 | enable = true; | ||
1689 | ret = wl1271_acx_rssi_snr_trigger(wl, enable, | ||
1690 | bss_conf->cqm_rssi_thold, | ||
1691 | bss_conf->cqm_rssi_hyst); | ||
1692 | if (ret < 0) | ||
1693 | goto out; | ||
1694 | wl->rssi_thold = bss_conf->cqm_rssi_thold; | ||
1695 | } | ||
1696 | |||
1706 | if ((changed & BSS_CHANGED_BSSID) && | 1697 | if ((changed & BSS_CHANGED_BSSID) && |
1707 | /* | 1698 | /* |
1708 | * Now we know the correct bssid, so we send a new join command | 1699 | * Now we know the correct bssid, so we send a new join command |
@@ -2283,7 +2274,8 @@ int wl1271_init_ieee80211(struct wl1271 *wl) | |||
2283 | IEEE80211_HW_SUPPORTS_PS | | 2274 | IEEE80211_HW_SUPPORTS_PS | |
2284 | IEEE80211_HW_SUPPORTS_UAPSD | | 2275 | IEEE80211_HW_SUPPORTS_UAPSD | |
2285 | IEEE80211_HW_HAS_RATE_CONTROL | | 2276 | IEEE80211_HW_HAS_RATE_CONTROL | |
2286 | IEEE80211_HW_CONNECTION_MONITOR; | 2277 | IEEE80211_HW_CONNECTION_MONITOR | |
2278 | IEEE80211_HW_SUPPORTS_CQM_RSSI; | ||
2287 | 2279 | ||
2288 | wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | | 2280 | wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | |
2289 | BIT(NL80211_IFTYPE_ADHOC); | 2281 | BIT(NL80211_IFTYPE_ADHOC); |