static ssize_t wcnss_wowenable_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { hdd_adapter_t *pAdapter = (hdd_adapter_t *)file->private_data; char cmd[MAX_USER_COMMAND_SIZE_WOWL_ENABLE + 1]; char *sptr, *token; v_U8_t wow_enable = 0; v_U8_t wow_mp = 0; v_U8_t wow_pbm = 0; if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s: Invalid adapter or adapter has invalid magic.", __func__); return -EINVAL; } if (!sme_IsFeatureSupportedByFW(WOW)) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: Wake-on-Wireless feature is not supported " "in firmware!", __func__); return -EINVAL; } if (count > MAX_USER_COMMAND_SIZE_WOWL_ENABLE) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: Command length is larger than %d bytes.", __func__, MAX_USER_COMMAND_SIZE_WOWL_ENABLE); return -EINVAL; } if (copy_from_user(cmd, buf, count)) return -EFAULT; cmd[count] = '\0'; sptr = cmd; token = strsep(&sptr, " "); if (!token) return -EINVAL; if (kstrtou8(token, 0, &wow_enable)) return -EINVAL; if (!wow_enable) { if (!hdd_exit_wowl(pAdapter)) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: hdd_exit_wowl failed!", __func__); return -EFAULT; } return count; } token = strsep(&sptr, " "); if (!token) return -EINVAL; if (kstrtou8(token, 0, &wow_mp)) return -EINVAL; if (wow_mp > 1) wow_mp = 1; token = strsep(&sptr, " "); if (!token) return -EINVAL; if (kstrtou8(token, 0, &wow_pbm)) return -EINVAL; if (wow_pbm > 1) wow_pbm = 1; if (!hdd_enter_wowl(pAdapter, wow_mp, wow_pbm)) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: hdd_enter_wowl failed!", __func__); return -EFAULT; } return count; }
static ssize_t wcnss_wowpattern_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { hdd_adapter_t *pAdapter = (hdd_adapter_t *)file->private_data; char cmd[MAX_USER_COMMAND_SIZE_WOWL_PATTERN + 1]; char *sptr, *token; v_U8_t pattern_idx = 0; v_U8_t pattern_offset = 0; char *pattern_buf; char *pattern_mask; if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) { VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s: Invalid adapter or adapter has invalid magic.", __func__); return -EINVAL; } if (!sme_IsFeatureSupportedByFW(WOW)) { VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: Wake-on-Wireless feature is not supported " "in firmware!", __func__); return -EINVAL; } if (count >= MAX_USER_COMMAND_SIZE_WOWL_PATTERN) { VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: Command length is larger than %d bytes.", __func__, MAX_USER_COMMAND_SIZE_WOWL_PATTERN); return -EINVAL; } if (copy_from_user(cmd, buf, count)) return -EFAULT; cmd[count] = '\0'; sptr = cmd; token = strsep(&sptr, " "); if (!token) return -EINVAL; if (kstrtou8(token, 0, &pattern_idx)) return -EINVAL; token = strsep(&sptr, " "); if (!token) { hdd_del_wowl_ptrn_debugfs(pAdapter, pattern_idx); return count; } if (kstrtou8(token, 0, &pattern_offset)) return -EINVAL; token = strsep(&sptr, " "); if (!token) return -EINVAL; pattern_buf = token; token = strsep(&sptr, " "); if (!token) return -EINVAL; pattern_mask = token; pattern_mask[strlen(pattern_mask) - 1] = '\0'; hdd_add_wowl_ptrn_debugfs(pAdapter, pattern_idx, pattern_offset, pattern_buf, pattern_mask); return count; }
static ssize_t wcnss_patterngen_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { hdd_adapter_t *pAdapter = (hdd_adapter_t *)file->private_data; hdd_context_t *pHddCtx; tSirAddPeriodicTxPtrn *addPeriodicTxPtrnParams; tSirDelPeriodicTxPtrn *delPeriodicTxPtrnParams; char *cmd, *sptr, *token; v_U8_t pattern_idx = 0; v_U8_t pattern_duration = 0; char *pattern_buf; v_U16_t pattern_len = 0; v_U16_t i = 0; if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) { VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s: Invalid adapter or adapter has invalid magic.", __func__); return -EINVAL; } pHddCtx = WLAN_HDD_GET_CTX(pAdapter); if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN)) { VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: Periodic Tx Pattern Offload feature is not supported " "in firmware!", __func__); return -EINVAL; } if (count < MAX_USER_COMMAND_SIZE_FRAME) cmd = vos_mem_malloc(count + 1); else { VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: Command length is larger than d% bytes.", __func__, MAX_USER_COMMAND_SIZE_FRAME); return -EINVAL; } if (!cmd) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: Memory allocation for cmd failed!", __func__); return -EFAULT; } if (copy_from_user(cmd, buf, count)) { vos_mem_free(cmd); return -EFAULT; } cmd[count] = '\0'; sptr = cmd; token = strsep(&sptr, " "); if (!token) goto failure; if (kstrtou8(token, 0, &pattern_idx)) goto failure; if (pattern_idx > (MAXNUM_PERIODIC_TX_PTRNS - 1)) { VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: Pattern index %d is not in the range (0 ~ %d).", __func__, pattern_idx, MAXNUM_PERIODIC_TX_PTRNS - 1); goto failure; } token = strsep(&sptr, " "); if (!token) goto failure; if (kstrtou8(token, 0, &pattern_duration)) goto failure; if (!pattern_duration) { delPeriodicTxPtrnParams = vos_mem_malloc(sizeof(tSirDelPeriodicTxPtrn)); if (!delPeriodicTxPtrnParams) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: Memory allocation for delPeriodicTxPtrnParams " "failed!", __func__); vos_mem_free(cmd); return -EFAULT; } delPeriodicTxPtrnParams->ucPatternIdBitmap = 1 << pattern_idx; vos_mem_copy(delPeriodicTxPtrnParams->macAddress, pAdapter->macAddressCurrent.bytes, 6); if (eHAL_STATUS_SUCCESS != sme_DelPeriodicTxPtrn(pHddCtx->hHal, delPeriodicTxPtrnParams)) { VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: sme_DelPeriodicTxPtrn() failed!", __func__); vos_mem_free(delPeriodicTxPtrnParams); goto failure; } vos_mem_free(delPeriodicTxPtrnParams); vos_mem_free(cmd); return count; } if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) { VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: Not in Connected state!", __func__); goto failure; } token = strsep(&sptr, " "); if (!token) goto failure; pattern_buf = token; pattern_buf[strlen(pattern_buf) - 1] = '\0'; pattern_len = strlen(pattern_buf); if (pattern_len % 2) { VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: Malformed pattern!", __func__); goto failure; } else pattern_len >>= 1; if (pattern_len < 14 || pattern_len > PERIODIC_TX_PTRN_MAX_SIZE) { VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: Not an 802.3 frame!", __func__); goto failure; } addPeriodicTxPtrnParams = vos_mem_malloc(sizeof(tSirAddPeriodicTxPtrn)); if (!addPeriodicTxPtrnParams) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: Memory allocation for addPeriodicTxPtrnParams " "failed!", __func__); vos_mem_free(cmd); return -EFAULT; } addPeriodicTxPtrnParams->ucPtrnId = pattern_idx; addPeriodicTxPtrnParams->usPtrnIntervalMs = pattern_duration * 500; addPeriodicTxPtrnParams->ucPtrnSize = pattern_len; vos_mem_copy(addPeriodicTxPtrnParams->macAddress, pAdapter->macAddressCurrent.bytes, 6); for(i = 0; i < addPeriodicTxPtrnParams->ucPtrnSize; i++) { addPeriodicTxPtrnParams->ucPattern[i] = (hdd_parse_hex(pattern_buf[0]) << 4) + hdd_parse_hex(pattern_buf[1]); pattern_buf += 2; } if (eHAL_STATUS_SUCCESS != sme_AddPeriodicTxPtrn(pHddCtx->hHal, addPeriodicTxPtrnParams)) { VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: sme_AddPeriodicTxPtrn() failed!", __func__); vos_mem_free(addPeriodicTxPtrnParams); goto failure; } vos_mem_free(addPeriodicTxPtrnParams); vos_mem_free(cmd); return count; failure: vos_mem_free(cmd); return -EINVAL; }
/** * __wcnss_wowenable_write() - write wow enable * @file: file pointer * @buf: buffer * @count: count * @ppos: position pointer * * Return: 0 on success, error number otherwise */ static ssize_t __wcnss_wowenable_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { hdd_adapter_t *pAdapter; hdd_context_t *hdd_ctx; char cmd[MAX_USER_COMMAND_SIZE_WOWL_ENABLE + 1]; char *sptr, *token; v_U8_t wow_enable = 0; v_U8_t wow_mp = 0; v_U8_t wow_pbm = 0; int ret; ENTER(); pAdapter = (hdd_adapter_t *)file->private_data; if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s: Invalid adapter or adapter has invalid magic.", __func__); return -EINVAL; } hdd_ctx = WLAN_HDD_GET_CTX(pAdapter); ret = wlan_hdd_validate_context(hdd_ctx); if (0 != ret) return ret; if (!sme_IsFeatureSupportedByFW(WOW)) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: Wake-on-Wireless feature is not supported " "in firmware!", __func__); return -EINVAL; } if (count > MAX_USER_COMMAND_SIZE_WOWL_ENABLE) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: Command length is larger than %d bytes.", __func__, MAX_USER_COMMAND_SIZE_WOWL_ENABLE); return -EINVAL; } /* Get command from user */ if (copy_from_user(cmd, buf, count)) return -EFAULT; cmd[count] = '\0'; sptr = cmd; /* Get enable or disable wow */ token = strsep(&sptr, " "); if (!token) return -EINVAL; if (kstrtou8(token, 0, &wow_enable)) return -EINVAL; /* Disable wow */ if (!wow_enable) { if (!hdd_exit_wowl(pAdapter)) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: hdd_exit_wowl failed!", __func__); return -EFAULT; } return count; } /* Get enable or disable magic packet mode */ token = strsep(&sptr, " "); if (!token) return -EINVAL; if (kstrtou8(token, 0, &wow_mp)) return -EINVAL; if (wow_mp > 1) wow_mp = 1; /* Get enable or disable pattern byte matching mode */ token = strsep(&sptr, " "); if (!token) return -EINVAL; if (kstrtou8(token, 0, &wow_pbm)) return -EINVAL; if (wow_pbm > 1) wow_pbm = 1; if (!hdd_enter_wowl(pAdapter, wow_mp, wow_pbm)) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: hdd_enter_wowl failed!", __func__); return -EFAULT; } EXIT(); return count; }