aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorAmitkumar Karwar <akarwar@marvell.com>2012-03-15 23:51:51 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-04-09 16:06:00 -0400
commitfa444bf88ce2ba17d24dd0bb279e3106acf86bed (patch)
tree010f901a998aa5856cb2062fb4eec0cd81f98372 /drivers/net/wireless
parent7013d3e267ef41b3dfdfedbbe6c3d3e666f0f138 (diff)
mwifiex: add set_cqm_rssi_config handler support
In this handler LOW_RSSI and HIGH_RSSI events are subscribed to FW using provided threshold value so that FW will monitor connection quality and trigger any of these events. Driver will notify cfg80211 about connection quality based on inputs from FW and provided hysteresis. Signed-off-by: Amitkumar Karwar <akarwar@marvell.com> Signed-off-by: Yogesh Ashok Powar <yogeshp@marvell.com> Signed-off-by: Bing Zhao <bzhao@marvell.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c40
-rw-r--r--drivers/net/wireless/mwifiex/fw.h17
-rw-r--r--drivers/net/wireless/mwifiex/ioctl.h21
-rw-r--r--drivers/net/wireless/mwifiex/main.h3
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmd.c98
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmdresp.c50
-rw-r--r--drivers/net/wireless/mwifiex/sta_event.c12
7 files changed, 241 insertions, 0 deletions
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 96c1e3b24da..c7e89188c35 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -766,6 +766,45 @@ static int mwifiex_cfg80211_set_bitrate_mask(struct wiphy *wiphy,
766} 766}
767 767
768/* 768/*
769 * CFG802.11 operation handler for connection quality monitoring.
770 *
771 * This function subscribes/unsubscribes HIGH_RSSI and LOW_RSSI
772 * events to FW.
773 */
774static int mwifiex_cfg80211_set_cqm_rssi_config(struct wiphy *wiphy,
775 struct net_device *dev,
776 s32 rssi_thold, u32 rssi_hyst)
777{
778 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
779 struct mwifiex_ds_misc_subsc_evt subsc_evt;
780
781 priv->cqm_rssi_thold = rssi_thold;
782 priv->cqm_rssi_hyst = rssi_hyst;
783
784 memset(&subsc_evt, 0x00, sizeof(struct mwifiex_ds_misc_subsc_evt));
785 subsc_evt.events = BITMASK_BCN_RSSI_LOW | BITMASK_BCN_RSSI_HIGH;
786
787 /* Subscribe/unsubscribe low and high rssi events */
788 if (rssi_thold && rssi_hyst) {
789 subsc_evt.action = HostCmd_ACT_BITWISE_SET;
790 subsc_evt.bcn_l_rssi_cfg.abs_value = abs(rssi_thold);
791 subsc_evt.bcn_h_rssi_cfg.abs_value = abs(rssi_thold);
792 subsc_evt.bcn_l_rssi_cfg.evt_freq = 1;
793 subsc_evt.bcn_h_rssi_cfg.evt_freq = 1;
794 return mwifiex_send_cmd_sync(priv,
795 HostCmd_CMD_802_11_SUBSCRIBE_EVENT,
796 0, 0, &subsc_evt);
797 } else {
798 subsc_evt.action = HostCmd_ACT_BITWISE_CLR;
799 return mwifiex_send_cmd_sync(priv,
800 HostCmd_CMD_802_11_SUBSCRIBE_EVENT,
801 0, 0, &subsc_evt);
802 }
803
804 return 0;
805}
806
807/*
769 * CFG802.11 operation handler for disconnection request. 808 * CFG802.11 operation handler for disconnection request.
770 * 809 *
771 * This function does not work when there is already a disconnection 810 * This function does not work when there is already a disconnection
@@ -1367,6 +1406,7 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = {
1367 .set_power_mgmt = mwifiex_cfg80211_set_power_mgmt, 1406 .set_power_mgmt = mwifiex_cfg80211_set_power_mgmt,
1368 .set_tx_power = mwifiex_cfg80211_set_tx_power, 1407 .set_tx_power = mwifiex_cfg80211_set_tx_power,
1369 .set_bitrate_mask = mwifiex_cfg80211_set_bitrate_mask, 1408 .set_bitrate_mask = mwifiex_cfg80211_set_bitrate_mask,
1409 .set_cqm_rssi_config = mwifiex_cfg80211_set_cqm_rssi_config,
1370}; 1410};
1371 1411
1372/* 1412/*
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index 930ad2f4b1e..e3b8c7062db 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -92,10 +92,12 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
92#define TLV_TYPE_KEY_MATERIAL (PROPRIETARY_TLV_BASE_ID + 0) 92#define TLV_TYPE_KEY_MATERIAL (PROPRIETARY_TLV_BASE_ID + 0)
93#define TLV_TYPE_CHANLIST (PROPRIETARY_TLV_BASE_ID + 1) 93#define TLV_TYPE_CHANLIST (PROPRIETARY_TLV_BASE_ID + 1)
94#define TLV_TYPE_NUMPROBES (PROPRIETARY_TLV_BASE_ID + 2) 94#define TLV_TYPE_NUMPROBES (PROPRIETARY_TLV_BASE_ID + 2)
95#define TLV_TYPE_RSSI_LOW (PROPRIETARY_TLV_BASE_ID + 4)
95#define TLV_TYPE_PASSTHROUGH (PROPRIETARY_TLV_BASE_ID + 10) 96#define TLV_TYPE_PASSTHROUGH (PROPRIETARY_TLV_BASE_ID + 10)
96#define TLV_TYPE_WMMQSTATUS (PROPRIETARY_TLV_BASE_ID + 16) 97#define TLV_TYPE_WMMQSTATUS (PROPRIETARY_TLV_BASE_ID + 16)
97#define TLV_TYPE_WILDCARDSSID (PROPRIETARY_TLV_BASE_ID + 18) 98#define TLV_TYPE_WILDCARDSSID (PROPRIETARY_TLV_BASE_ID + 18)
98#define TLV_TYPE_TSFTIMESTAMP (PROPRIETARY_TLV_BASE_ID + 19) 99#define TLV_TYPE_TSFTIMESTAMP (PROPRIETARY_TLV_BASE_ID + 19)
100#define TLV_TYPE_RSSI_HIGH (PROPRIETARY_TLV_BASE_ID + 22)
99#define TLV_TYPE_AUTH_TYPE (PROPRIETARY_TLV_BASE_ID + 31) 101#define TLV_TYPE_AUTH_TYPE (PROPRIETARY_TLV_BASE_ID + 31)
100#define TLV_TYPE_CHANNELBANDLIST (PROPRIETARY_TLV_BASE_ID + 42) 102#define TLV_TYPE_CHANNELBANDLIST (PROPRIETARY_TLV_BASE_ID + 42)
101#define TLV_TYPE_RATE_DROP_CONTROL (PROPRIETARY_TLV_BASE_ID + 82) 103#define TLV_TYPE_RATE_DROP_CONTROL (PROPRIETARY_TLV_BASE_ID + 82)
@@ -194,6 +196,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
194#define HostCmd_CMD_802_11_KEY_MATERIAL 0x005e 196#define HostCmd_CMD_802_11_KEY_MATERIAL 0x005e
195#define HostCmd_CMD_802_11_BG_SCAN_QUERY 0x006c 197#define HostCmd_CMD_802_11_BG_SCAN_QUERY 0x006c
196#define HostCmd_CMD_WMM_GET_STATUS 0x0071 198#define HostCmd_CMD_WMM_GET_STATUS 0x0071
199#define HostCmd_CMD_802_11_SUBSCRIBE_EVENT 0x0075
197#define HostCmd_CMD_802_11_TX_RATE_QUERY 0x007f 200#define HostCmd_CMD_802_11_TX_RATE_QUERY 0x007f
198#define HostCmd_CMD_802_11_IBSS_COALESCING_STATUS 0x0083 201#define HostCmd_CMD_802_11_IBSS_COALESCING_STATUS 0x0083
199#define HostCmd_CMD_VERSION_EXT 0x0097 202#define HostCmd_CMD_VERSION_EXT 0x0097
@@ -228,6 +231,8 @@ enum ENH_PS_MODES {
228#define HostCmd_RET_BIT 0x8000 231#define HostCmd_RET_BIT 0x8000
229#define HostCmd_ACT_GEN_GET 0x0000 232#define HostCmd_ACT_GEN_GET 0x0000
230#define HostCmd_ACT_GEN_SET 0x0001 233#define HostCmd_ACT_GEN_SET 0x0001
234#define HostCmd_ACT_BITWISE_SET 0x0002
235#define HostCmd_ACT_BITWISE_CLR 0x0003
231#define HostCmd_RESULT_OK 0x0000 236#define HostCmd_RESULT_OK 0x0000
232 237
233#define HostCmd_ACT_MAC_RX_ON 0x0001 238#define HostCmd_ACT_MAC_RX_ON 0x0001
@@ -1146,6 +1151,17 @@ struct host_cmd_ds_pcie_details {
1146 u32 sleep_cookie_addr_hi; 1151 u32 sleep_cookie_addr_hi;
1147} __packed; 1152} __packed;
1148 1153
1154struct mwifiex_ie_types_rssi_threshold {
1155 struct mwifiex_ie_types_header header;
1156 u8 abs_value;
1157 u8 evt_freq;
1158} __packed;
1159
1160struct host_cmd_ds_802_11_subsc_evt {
1161 __le16 action;
1162 __le16 events;
1163} __packed;
1164
1149struct host_cmd_ds_command { 1165struct host_cmd_ds_command {
1150 __le16 command; 1166 __le16 command;
1151 __le16 size; 1167 __le16 size;
@@ -1195,6 +1211,7 @@ struct host_cmd_ds_command {
1195 struct host_cmd_ds_set_bss_mode bss_mode; 1211 struct host_cmd_ds_set_bss_mode bss_mode;
1196 struct host_cmd_ds_pcie_details pcie_host_spec; 1212 struct host_cmd_ds_pcie_details pcie_host_spec;
1197 struct host_cmd_ds_802_11_eeprom_access eeprom; 1213 struct host_cmd_ds_802_11_eeprom_access eeprom;
1214 struct host_cmd_ds_802_11_subsc_evt subsc_evt;
1198 } params; 1215 } params;
1199} __packed; 1216} __packed;
1200 1217
diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h
index 58fe0543704..99c06649f94 100644
--- a/drivers/net/wireless/mwifiex/ioctl.h
+++ b/drivers/net/wireless/mwifiex/ioctl.h
@@ -280,6 +280,27 @@ struct mwifiex_ds_misc_cmd {
280 u8 cmd[MWIFIEX_SIZE_OF_CMD_BUFFER]; 280 u8 cmd[MWIFIEX_SIZE_OF_CMD_BUFFER];
281}; 281};
282 282
283#define BITMASK_BCN_RSSI_LOW BIT(0)
284#define BITMASK_BCN_RSSI_HIGH BIT(4)
285
286enum subsc_evt_rssi_state {
287 EVENT_HANDLED,
288 RSSI_LOW_RECVD,
289 RSSI_HIGH_RECVD
290};
291
292struct subsc_evt_cfg {
293 u8 abs_value;
294 u8 evt_freq;
295};
296
297struct mwifiex_ds_misc_subsc_evt {
298 u16 action;
299 u16 events;
300 struct subsc_evt_cfg bcn_l_rssi_cfg;
301 struct subsc_evt_cfg bcn_h_rssi_cfg;
302};
303
283#define MWIFIEX_MAX_VSIE_LEN (256) 304#define MWIFIEX_MAX_VSIE_LEN (256)
284#define MWIFIEX_MAX_VSIE_NUM (8) 305#define MWIFIEX_MAX_VSIE_NUM (8)
285#define MWIFIEX_VSIE_MASK_SCAN 0x01 306#define MWIFIEX_VSIE_MASK_SCAN 0x01
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 964570ad2f3..3bbe1636473 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -458,6 +458,9 @@ struct mwifiex_private {
458 u8 country_code[IEEE80211_COUNTRY_STRING_LEN]; 458 u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
459 struct wps wps; 459 struct wps wps;
460 u8 scan_block; 460 u8 scan_block;
461 s32 cqm_rssi_thold;
462 u32 cqm_rssi_hyst;
463 u8 subsc_evt_rssi_state;
461}; 464};
462 465
463enum mwifiex_ba_status { 466enum mwifiex_ba_status {
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c
index 6c8e4594b48..e90c34d9c63 100644
--- a/drivers/net/wireless/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/mwifiex/sta_cmd.c
@@ -907,6 +907,101 @@ mwifiex_cmd_pcie_host_spec(struct mwifiex_private *priv,
907} 907}
908 908
909/* 909/*
910 * This function prepares command for event subscription, configuration
911 * and query. Events can be subscribed or unsubscribed. Current subscribed
912 * events can be queried. Also, current subscribed events are reported in
913 * every FW response.
914 */
915static int
916mwifiex_cmd_802_11_subsc_evt(struct mwifiex_private *priv,
917 struct host_cmd_ds_command *cmd,
918 struct mwifiex_ds_misc_subsc_evt *subsc_evt_cfg)
919{
920 struct host_cmd_ds_802_11_subsc_evt *subsc_evt = &cmd->params.subsc_evt;
921 struct mwifiex_ie_types_rssi_threshold *rssi_tlv;
922 u16 event_bitmap;
923 u8 *pos;
924
925 cmd->command = cpu_to_le16(HostCmd_CMD_802_11_SUBSCRIBE_EVENT);
926 cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_subsc_evt) +
927 S_DS_GEN);
928
929 subsc_evt->action = cpu_to_le16(subsc_evt_cfg->action);
930 dev_dbg(priv->adapter->dev, "cmd: action: %d\n", subsc_evt_cfg->action);
931
932 /*For query requests, no configuration TLV structures are to be added.*/
933 if (subsc_evt_cfg->action == HostCmd_ACT_GEN_GET)
934 return 0;
935
936 subsc_evt->events = cpu_to_le16(subsc_evt_cfg->events);
937
938 event_bitmap = subsc_evt_cfg->events;
939 dev_dbg(priv->adapter->dev, "cmd: event bitmap : %16x\n",
940 event_bitmap);
941
942 if (((subsc_evt_cfg->action == HostCmd_ACT_BITWISE_CLR) ||
943 (subsc_evt_cfg->action == HostCmd_ACT_BITWISE_SET)) &&
944 (event_bitmap == 0)) {
945 dev_dbg(priv->adapter->dev, "Error: No event specified "
946 "for bitwise action type\n");
947 return -EINVAL;
948 }
949
950 /*
951 * Append TLV structures for each of the specified events for
952 * subscribing or re-configuring. This is not required for
953 * bitwise unsubscribing request.
954 */
955 if (subsc_evt_cfg->action == HostCmd_ACT_BITWISE_CLR)
956 return 0;
957
958 pos = ((u8 *)subsc_evt) +
959 sizeof(struct host_cmd_ds_802_11_subsc_evt);
960
961 if (event_bitmap & BITMASK_BCN_RSSI_LOW) {
962 rssi_tlv = (struct mwifiex_ie_types_rssi_threshold *) pos;
963
964 rssi_tlv->header.type = cpu_to_le16(TLV_TYPE_RSSI_LOW);
965 rssi_tlv->header.len =
966 cpu_to_le16(sizeof(struct mwifiex_ie_types_rssi_threshold) -
967 sizeof(struct mwifiex_ie_types_header));
968 rssi_tlv->abs_value = subsc_evt_cfg->bcn_l_rssi_cfg.abs_value;
969 rssi_tlv->evt_freq = subsc_evt_cfg->bcn_l_rssi_cfg.evt_freq;
970
971 dev_dbg(priv->adapter->dev, "Cfg Beacon Low Rssi event, "
972 "RSSI:-%d dBm, Freq:%d\n",
973 subsc_evt_cfg->bcn_l_rssi_cfg.abs_value,
974 subsc_evt_cfg->bcn_l_rssi_cfg.evt_freq);
975
976 pos += sizeof(struct mwifiex_ie_types_rssi_threshold);
977 le16_add_cpu(&cmd->size,
978 sizeof(struct mwifiex_ie_types_rssi_threshold));
979 }
980
981 if (event_bitmap & BITMASK_BCN_RSSI_HIGH) {
982 rssi_tlv = (struct mwifiex_ie_types_rssi_threshold *) pos;
983
984 rssi_tlv->header.type = cpu_to_le16(TLV_TYPE_RSSI_HIGH);
985 rssi_tlv->header.len =
986 cpu_to_le16(sizeof(struct mwifiex_ie_types_rssi_threshold) -
987 sizeof(struct mwifiex_ie_types_header));
988 rssi_tlv->abs_value = subsc_evt_cfg->bcn_h_rssi_cfg.abs_value;
989 rssi_tlv->evt_freq = subsc_evt_cfg->bcn_h_rssi_cfg.evt_freq;
990
991 dev_dbg(priv->adapter->dev, "Cfg Beacon Low Rssi event, "
992 "RSSI:-%d dBm, Freq:%d\n",
993 subsc_evt_cfg->bcn_h_rssi_cfg.abs_value,
994 subsc_evt_cfg->bcn_h_rssi_cfg.evt_freq);
995
996 pos += sizeof(struct mwifiex_ie_types_rssi_threshold);
997 le16_add_cpu(&cmd->size,
998 sizeof(struct mwifiex_ie_types_rssi_threshold));
999 }
1000
1001 return 0;
1002}
1003
1004/*
910 * This function prepares the commands before sending them to the firmware. 1005 * This function prepares the commands before sending them to the firmware.
911 * 1006 *
912 * This is a generic function which calls specific command preparation 1007 * This is a generic function which calls specific command preparation
@@ -1086,6 +1181,9 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
1086 case HostCmd_CMD_PCIE_DESC_DETAILS: 1181 case HostCmd_CMD_PCIE_DESC_DETAILS:
1087 ret = mwifiex_cmd_pcie_host_spec(priv, cmd_ptr, cmd_action); 1182 ret = mwifiex_cmd_pcie_host_spec(priv, cmd_ptr, cmd_action);
1088 break; 1183 break;
1184 case HostCmd_CMD_802_11_SUBSCRIBE_EVENT:
1185 ret = mwifiex_cmd_802_11_subsc_evt(priv, cmd_ptr, data_buf);
1186 break;
1089 default: 1187 default:
1090 dev_err(priv->adapter->dev, 1188 dev_err(priv->adapter->dev,
1091 "PREP_CMD: unknown cmd- %#x\n", cmd_no); 1189 "PREP_CMD: unknown cmd- %#x\n", cmd_no);
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index cd90b6f0969..3aa54243dea 100644
--- a/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -123,6 +123,7 @@ static int mwifiex_ret_802_11_rssi_info(struct mwifiex_private *priv,
123{ 123{
124 struct host_cmd_ds_802_11_rssi_info_rsp *rssi_info_rsp = 124 struct host_cmd_ds_802_11_rssi_info_rsp *rssi_info_rsp =
125 &resp->params.rssi_info_rsp; 125 &resp->params.rssi_info_rsp;
126 struct mwifiex_ds_misc_subsc_evt subsc_evt;
126 127
127 priv->data_rssi_last = le16_to_cpu(rssi_info_rsp->data_rssi_last); 128 priv->data_rssi_last = le16_to_cpu(rssi_info_rsp->data_rssi_last);
128 priv->data_nf_last = le16_to_cpu(rssi_info_rsp->data_nf_last); 129 priv->data_nf_last = le16_to_cpu(rssi_info_rsp->data_nf_last);
@@ -136,6 +137,30 @@ static int mwifiex_ret_802_11_rssi_info(struct mwifiex_private *priv,
136 priv->bcn_rssi_avg = le16_to_cpu(rssi_info_rsp->bcn_rssi_avg); 137 priv->bcn_rssi_avg = le16_to_cpu(rssi_info_rsp->bcn_rssi_avg);
137 priv->bcn_nf_avg = le16_to_cpu(rssi_info_rsp->bcn_nf_avg); 138 priv->bcn_nf_avg = le16_to_cpu(rssi_info_rsp->bcn_nf_avg);
138 139
140 if (priv->subsc_evt_rssi_state == EVENT_HANDLED)
141 return 0;
142
143 /* Resubscribe low and high rssi events with new thresholds */
144 memset(&subsc_evt, 0x00, sizeof(struct mwifiex_ds_misc_subsc_evt));
145 subsc_evt.events = BITMASK_BCN_RSSI_LOW | BITMASK_BCN_RSSI_HIGH;
146 subsc_evt.action = HostCmd_ACT_BITWISE_SET;
147 if (priv->subsc_evt_rssi_state == RSSI_LOW_RECVD) {
148 subsc_evt.bcn_l_rssi_cfg.abs_value = abs(priv->bcn_rssi_avg -
149 priv->cqm_rssi_hyst);
150 subsc_evt.bcn_h_rssi_cfg.abs_value = abs(priv->cqm_rssi_thold);
151 } else if (priv->subsc_evt_rssi_state == RSSI_HIGH_RECVD) {
152 subsc_evt.bcn_l_rssi_cfg.abs_value = abs(priv->cqm_rssi_thold);
153 subsc_evt.bcn_h_rssi_cfg.abs_value = abs(priv->bcn_rssi_avg +
154 priv->cqm_rssi_hyst);
155 }
156 subsc_evt.bcn_l_rssi_cfg.evt_freq = 1;
157 subsc_evt.bcn_h_rssi_cfg.evt_freq = 1;
158
159 priv->subsc_evt_rssi_state = EVENT_HANDLED;
160
161 mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11_SUBSCRIBE_EVENT,
162 0, 0, &subsc_evt);
163
139 return 0; 164 return 0;
140} 165}
141 166
@@ -755,6 +780,28 @@ static int mwifiex_ret_ibss_coalescing_status(struct mwifiex_private *priv,
755} 780}
756 781
757/* 782/*
783 * This function handles the command response for subscribe event command.
784 */
785static int mwifiex_ret_subsc_evt(struct mwifiex_private *priv,
786 struct host_cmd_ds_command *resp,
787 struct mwifiex_ds_misc_subsc_evt *sub_event)
788{
789 struct host_cmd_ds_802_11_subsc_evt *cmd_sub_event =
790 (struct host_cmd_ds_802_11_subsc_evt *)&resp->params.subsc_evt;
791
792 /* For every subscribe event command (Get/Set/Clear), FW reports the
793 * current set of subscribed events*/
794 dev_dbg(priv->adapter->dev, "Bitmap of currently subscribed events: %16x\n",
795 le16_to_cpu(cmd_sub_event->events));
796
797 /*Return the subscribed event info for a Get request*/
798 if (sub_event)
799 sub_event->events = le16_to_cpu(cmd_sub_event->events);
800
801 return 0;
802}
803
804/*
758 * This function handles the command responses. 805 * This function handles the command responses.
759 * 806 *
760 * This is a generic function, which calls command specific 807 * This is a generic function, which calls command specific
@@ -894,6 +941,9 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no,
894 break; 941 break;
895 case HostCmd_CMD_PCIE_DESC_DETAILS: 942 case HostCmd_CMD_PCIE_DESC_DETAILS:
896 break; 943 break;
944 case HostCmd_CMD_802_11_SUBSCRIBE_EVENT:
945 ret = mwifiex_ret_subsc_evt(priv, resp, data_buf);
946 break;
897 default: 947 default:
898 dev_err(adapter->dev, "CMD_RESP: unknown cmd response %#x\n", 948 dev_err(adapter->dev, "CMD_RESP: unknown cmd response %#x\n",
899 resp->command); 949 resp->command);
diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c
index 33b311ce125..f6bbb9307f8 100644
--- a/drivers/net/wireless/mwifiex/sta_event.c
+++ b/drivers/net/wireless/mwifiex/sta_event.c
@@ -314,6 +314,12 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
314 break; 314 break;
315 315
316 case EVENT_RSSI_LOW: 316 case EVENT_RSSI_LOW:
317 cfg80211_cqm_rssi_notify(priv->netdev,
318 NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW,
319 GFP_KERNEL);
320 mwifiex_send_cmd_async(priv, HostCmd_CMD_RSSI_INFO,
321 HostCmd_ACT_GEN_GET, 0, NULL);
322 priv->subsc_evt_rssi_state = RSSI_LOW_RECVD;
317 dev_dbg(adapter->dev, "event: Beacon RSSI_LOW\n"); 323 dev_dbg(adapter->dev, "event: Beacon RSSI_LOW\n");
318 break; 324 break;
319 case EVENT_SNR_LOW: 325 case EVENT_SNR_LOW:
@@ -323,6 +329,12 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
323 dev_dbg(adapter->dev, "event: MAX_FAIL\n"); 329 dev_dbg(adapter->dev, "event: MAX_FAIL\n");
324 break; 330 break;
325 case EVENT_RSSI_HIGH: 331 case EVENT_RSSI_HIGH:
332 cfg80211_cqm_rssi_notify(priv->netdev,
333 NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH,
334 GFP_KERNEL);
335 mwifiex_send_cmd_async(priv, HostCmd_CMD_RSSI_INFO,
336 HostCmd_ACT_GEN_GET, 0, NULL);
337 priv->subsc_evt_rssi_state = RSSI_HIGH_RECVD;
326 dev_dbg(adapter->dev, "event: Beacon RSSI_HIGH\n"); 338 dev_dbg(adapter->dev, "event: Beacon RSSI_HIGH\n");
327 break; 339 break;
328 case EVENT_SNR_HIGH: 340 case EVENT_SNR_HIGH: