1 /* 2 * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for 5 * any purpose with or without fee is hereby granted, provided that the 6 * above copyright notice and this permission notice appear in all 7 * copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 * PERFORMANCE OF THIS SOFTWARE. 17 */ 18 /** 19 * DOC: Implements low power heart beat offload feature API's 20 */ 21 22 #include "wlan_pmo_main.h" 23 #include "wlan_pmo_lphb.h" 24 #include "wlan_pmo_tgt_api.h" 25 #include "wlan_pmo_obj_mgmt_public_struct.h" 26 27 #ifdef FEATURE_WLAN_LPHB 28 /** 29 * pmo_core_send_lphb_enable() - enable command of LPHB configuration requests 30 * @psoc: objmgr psoc handle 31 * @psoc_ctx: pmo private psoc ctx 32 * @lphb_conf_req: lphb request which need s to configure in fwr 33 * @by_user: whether this call is from user or cached resent 34 * 35 * Return: QDF status 36 */ pmo_core_send_lphb_enable(struct wlan_objmgr_psoc * psoc,struct pmo_psoc_priv_obj * psoc_ctx,struct pmo_lphb_req * lphb_conf_req,bool by_user)37 static QDF_STATUS pmo_core_send_lphb_enable(struct wlan_objmgr_psoc *psoc, 38 struct pmo_psoc_priv_obj *psoc_ctx, 39 struct pmo_lphb_req *lphb_conf_req, bool by_user) 40 { 41 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; 42 struct pmo_lphb_enable_req *ts_lphb_enable; 43 int i; 44 45 if (!lphb_conf_req) { 46 pmo_err("LPHB configuration is NULL"); 47 return QDF_STATUS_E_FAILURE; 48 } 49 50 ts_lphb_enable = &(lphb_conf_req->params.lphb_enable_req); 51 qdf_status = pmo_tgt_send_lphb_enable(psoc, ts_lphb_enable); 52 if (qdf_status != QDF_STATUS_SUCCESS) 53 goto out; 54 55 /* No need to cache non user request */ 56 if (!by_user) { 57 qdf_status = QDF_STATUS_SUCCESS; 58 goto out; 59 } 60 61 /* target already configured, now cache command status */ 62 if (ts_lphb_enable->enable && ts_lphb_enable->item > 0) { 63 i = ts_lphb_enable->item - 1; 64 qdf_spin_lock_bh(&psoc_ctx->lock); 65 psoc_ctx->wow.lphb_cache[i].cmd 66 = pmo_lphb_set_en_param_indid; 67 psoc_ctx->wow.lphb_cache[i].params.lphb_enable_req.enable = 68 ts_lphb_enable->enable; 69 psoc_ctx->wow.lphb_cache[i].params.lphb_enable_req.item = 70 ts_lphb_enable->item; 71 psoc_ctx->wow.lphb_cache[i].params.lphb_enable_req.session = 72 ts_lphb_enable->session; 73 qdf_spin_unlock_bh(&psoc_ctx->lock); 74 pmo_debug("cached LPHB status in WMA context for item %d", i); 75 } else { 76 qdf_spin_lock_bh(&psoc_ctx->lock); 77 qdf_mem_zero((void *)&psoc_ctx->wow.lphb_cache, 78 sizeof(psoc_ctx->wow.lphb_cache)); 79 qdf_spin_unlock_bh(&psoc_ctx->lock); 80 pmo_debug("cleared all cached LPHB status in WMA context"); 81 } 82 83 out: 84 return qdf_status; 85 } 86 87 /** 88 * pmo_core_send_lphb_tcp_params() - Send tcp params of LPHB requests 89 * @psoc: objmgr psoc handle 90 * @lphb_conf_req: lphb request which needs to be configured in fwr 91 * 92 * Return: QDF status 93 */ 94 static pmo_core_send_lphb_tcp_params(struct wlan_objmgr_psoc * psoc,struct pmo_lphb_req * lphb_conf_req)95 QDF_STATUS pmo_core_send_lphb_tcp_params(struct wlan_objmgr_psoc *psoc, 96 struct pmo_lphb_req *lphb_conf_req) 97 { 98 return pmo_tgt_send_lphb_tcp_params(psoc, 99 &lphb_conf_req->params.lphb_tcp_params); 100 101 } 102 103 /** 104 * pmo_core_send_lphb_tcp_pkt_filter() - Send tcp packet filter command of LPHB 105 * @psoc: objmgr psoc handle 106 * @lphb_conf_req: lphb request which needs to be configured in fwr 107 * 108 * Return: QDF status 109 */ 110 static pmo_core_send_lphb_tcp_pkt_filter(struct wlan_objmgr_psoc * psoc,struct pmo_lphb_req * lphb_conf_req)111 QDF_STATUS pmo_core_send_lphb_tcp_pkt_filter(struct wlan_objmgr_psoc *psoc, 112 struct pmo_lphb_req *lphb_conf_req) 113 { 114 return pmo_tgt_send_lphb_tcp_pkt_filter(psoc, 115 &lphb_conf_req->params.lphb_tcp_filter_req); 116 } 117 118 /** 119 * pmo_core_send_lphb_udp_params() - Send udp param command of LPHB 120 * @psoc: objmgr psoc handle 121 * @lphb_conf_req: lphb request which needs to be configured in fwr 122 * 123 * Return: QDF status 124 */ 125 static pmo_core_send_lphb_udp_params(struct wlan_objmgr_psoc * psoc,struct pmo_lphb_req * lphb_conf_req)126 QDF_STATUS pmo_core_send_lphb_udp_params(struct wlan_objmgr_psoc *psoc, 127 struct pmo_lphb_req *lphb_conf_req) 128 { 129 return pmo_tgt_send_lphb_udp_params(psoc, 130 &lphb_conf_req->params.lphb_udp_params); 131 } 132 133 /** 134 * pmo_core_send_lphb_udp_pkt_filter() - Send udp pkt filter command of LPHB 135 * @psoc: objmgr psoc handle 136 * @lphb_conf_req: lphb request which need s to configure in fwr 137 * 138 * Return: QDF status 139 */ 140 static pmo_core_send_lphb_udp_pkt_filter(struct wlan_objmgr_psoc * psoc,struct pmo_lphb_req * lphb_conf_req)141 QDF_STATUS pmo_core_send_lphb_udp_pkt_filter(struct wlan_objmgr_psoc *psoc, 142 struct pmo_lphb_req *lphb_conf_req) 143 { 144 return pmo_tgt_send_lphb_udp_pkt_filter(psoc, 145 &lphb_conf_req->params.lphb_udp_filter_req); 146 } 147 148 /** 149 * pmo_process_lphb_conf_req() - handle LPHB configuration requests 150 * @psoc: objmgr psoc handle 151 * @psoc_ctx: pmo private psoc ctx 152 * @lphb_conf_req: lphb request which needs to be configured in fwr 153 * 154 * Return: QDF status 155 */ pmo_process_lphb_conf_req(struct wlan_objmgr_psoc * psoc,struct pmo_psoc_priv_obj * psoc_ctx,struct pmo_lphb_req * lphb_conf_req)156 static QDF_STATUS pmo_process_lphb_conf_req(struct wlan_objmgr_psoc *psoc, 157 struct pmo_psoc_priv_obj *psoc_ctx, 158 struct pmo_lphb_req *lphb_conf_req) 159 { 160 QDF_STATUS status = QDF_STATUS_SUCCESS; 161 162 pmo_debug("LPHB configuration cmd id is %d", lphb_conf_req->cmd); 163 switch (lphb_conf_req->cmd) { 164 case pmo_lphb_set_en_param_indid: 165 status = pmo_core_send_lphb_enable(psoc, psoc_ctx, 166 lphb_conf_req, true); 167 break; 168 169 case pmo_lphb_set_tcp_pararm_indid: 170 status = pmo_core_send_lphb_tcp_params(psoc, lphb_conf_req); 171 break; 172 173 case pmo_lphb_set_tcp_pkt_filter_indid: 174 status = pmo_core_send_lphb_tcp_pkt_filter(psoc, lphb_conf_req); 175 break; 176 177 case pmo_lphb_set_udp_pararm_indid: 178 status = pmo_core_send_lphb_udp_params(psoc, lphb_conf_req); 179 break; 180 181 case pmo_lphb_set_udp_pkt_filter_indid: 182 status = pmo_core_send_lphb_udp_pkt_filter(psoc, lphb_conf_req); 183 break; 184 185 case pmo_lphb_set_network_info_indid: 186 default: 187 break; 188 } 189 190 return status; 191 } 192 pmo_core_apply_lphb(struct wlan_objmgr_psoc * psoc)193 void pmo_core_apply_lphb(struct wlan_objmgr_psoc *psoc) 194 { 195 int i; 196 struct pmo_psoc_priv_obj *psoc_ctx; 197 198 psoc_ctx = pmo_psoc_get_priv(psoc); 199 200 pmo_debug("checking LPHB cache"); 201 for (i = 0; i < 2; i++) { 202 if (psoc_ctx->wow.lphb_cache[i].params.lphb_enable_req.enable) { 203 pmo_debug("LPHB cache for item %d is marked as enable", 204 i + 1); 205 pmo_core_send_lphb_enable(psoc, psoc_ctx, 206 &(psoc_ctx->wow.lphb_cache[i]), false); 207 } 208 } 209 } 210 pmo_core_lphb_config_req(struct wlan_objmgr_psoc * psoc,struct pmo_lphb_req * lphb_req,void * lphb_cb_ctx,pmo_lphb_callback callback)211 QDF_STATUS pmo_core_lphb_config_req(struct wlan_objmgr_psoc *psoc, 212 struct pmo_lphb_req *lphb_req, void *lphb_cb_ctx, 213 pmo_lphb_callback callback) 214 { 215 struct pmo_psoc_priv_obj *psoc_ctx; 216 217 if (!lphb_req) { 218 pmo_err("LPHB configuration is NULL"); 219 return QDF_STATUS_E_NULL_VALUE; 220 } 221 222 psoc_ctx = pmo_psoc_get_priv(psoc); 223 224 if (pmo_lphb_set_en_param_indid == lphb_req->cmd) { 225 if (!lphb_cb_ctx) { 226 pmo_err("lphb callback context is null"); 227 return QDF_STATUS_E_NULL_VALUE; 228 } 229 if (!callback) { 230 pmo_err("lphb callback function is null"); 231 return QDF_STATUS_E_NULL_VALUE; 232 } 233 qdf_spin_lock_bh(&psoc_ctx->lock); 234 psoc_ctx->wow.lphb_cb_ctx = lphb_cb_ctx; 235 psoc_ctx->wow.lphb_cb = callback; 236 qdf_spin_unlock_bh(&psoc_ctx->lock); 237 } 238 239 return pmo_process_lphb_conf_req(psoc, psoc_ctx, lphb_req); 240 } 241 242 #endif /* FEATURE_WLAN_LPHB */ 243 244