void unifi_mgt_mib_get_cfm(void *drvpriv, void* appHandle, unifi_Status status, CsrUint16 mibAttributeLength, const CsrUint8 *mibAttribute) { unifi_priv_t *priv = (unifi_priv_t*)drvpriv; if (priv == NULL) { unifi_error(NULL, "unifi_mgt_mib_get_cfm: Invalid ospriv.\n"); return; } if (mibAttribute == NULL) { unifi_error(priv, "unifi_mgt_mib_get_cfm: Empty reply.\n"); sme_complete_request(priv, status); return; } if ((priv->mib_cfm_buffer != NULL) && (priv->mib_cfm_buffer_length >= mibAttributeLength)) { memcpy(priv->mib_cfm_buffer, mibAttribute, mibAttributeLength); priv->mib_cfm_buffer_length = mibAttributeLength; } else { unifi_error(priv, "unifi_mgt_mib_get_cfm: No room to store MIB data (have=%d need=%d).\n", priv->mib_cfm_buffer_length, mibAttributeLength); } sme_complete_request(priv, status); }
int unifi_putest_stop(unifi_priv_t *priv, unsigned char *arg) { int r; CsrInt32 csr_r; /* Application may have stopped the XAPs, but they are needed for reset */ csr_r = unifi_start_processors(priv->card); if (csr_r) { unifi_error(priv, "Failed to start XAPs. Hard reset required.\n"); } /* At this point function 1 is enabled and the XAPs are running, so it is * safe to let the card power down. Power is restored later, asynchronously, * during the wifi_on requested by the SME. */ priv->ptest_mode = 0; /* Power off UniFi */ CsrSdioPowerOff(priv->sdio); /* Resume the SME and UniFi */ r = sme_sys_resume(priv); if (r) { unifi_error(priv, "unifi_putest_stop: failed to resume UniFi\n"); } return r; }
int unifi_cfg_power(unifi_priv_t *priv, unsigned char *arg) { unifi_cfg_power_t cfg_power; int rc; if (get_user(cfg_power, (unifi_cfg_power_t*)(((unifi_cfg_command_t*)arg) + 1))) { unifi_error(priv, "UNIFI_CFG: Failed to get the argument\n"); return -EFAULT; } switch (cfg_power) { case UNIFI_CFG_POWER_OFF: rc = sme_sys_suspend(priv); if (rc) { return rc; } break; case UNIFI_CFG_POWER_ON: rc = sme_sys_resume(priv); if (rc) { return rc; } break; default: unifi_error(priv, "WIFI POWER: Unknown value.\n"); return -EINVAL; } return 0; }
int sme_mgt_sme_config_set(unifi_priv_t *priv, CsrWifiSmeStaConfig *staConfig, CsrWifiSmeDeviceConfig *deviceConfig) { #ifdef CSR_SME_USERSPACE int r; if (priv->smepriv == NULL) { unifi_error(priv, "sme_mgt_sme_config_set: invalid smepriv\n"); return -EIO; } r = sme_init_request(priv); if (r) { return -EIO; } CsrWifiSmeSmeStaConfigSetReqSend(0, CSR_WIFI_INTERFACE_IN_USE, *staConfig); r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); if (r) { return r; } unifi_trace(priv, UDBG4, "sme_mgt_sme_config_set: CsrWifiSmeSmeStaConfigSetReq <-- (r=%d status=%d)\n", r, priv->sme_reply.reply_status); r = sme_init_request(priv); if (r) { return -EIO; } CsrWifiSmeSmeCommonConfigSetReqSend(0, *deviceConfig); r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); if (r) { return r; } unifi_trace(priv, UDBG4, "sme_mgt_sme_config_set: CsrWifiSmeSmeCommonConfigSetReq <-- (r=%d status=%d)\n", r, priv->sme_reply.reply_status); return convert_sme_error(priv->sme_reply.reply_status); #else CsrResult status; if (priv->smepriv == NULL) { unifi_error(priv, "sme_mgt_sme_config_set: invalid smepriv\n"); return -EIO; } CsrWifiSmeMgtClaimSyncAccess(priv->smepriv); status = CsrWifiSmeMgtSmeConfigSetReq(priv->smepriv, *staConfig); status = CsrWifiSmeMgtDeviceConfigSetReq(priv->smepriv, *deviceConfig); CsrWifiSmeMgtReleaseSyncAccess(priv->smepriv); return convert_sme_error(status); #endif }
/* * --------------------------------------------------------------------------- * uf_register_netdev * * Registers the network interface, installes the qdisc, * and registers the inet handler. * In the porting exercise, register the driver to the network * stack if necessary. * * Arguments: * priv Pointer to driver context. * * Returns: * O on success, non-zero otherwise. * * Notes: * We will only unregister when the card is ejected, so we must * only do it once. * --------------------------------------------------------------------------- */ int uf_register_netdev(unifi_priv_t *priv, int interfaceTag) { int r; netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag]; if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) { unifi_error(priv, "uf_register_netdev bad interfaceTag\n"); return -EINVAL; } /* * Allocates a device number and registers device with the network * stack. */ unifi_trace(priv, UDBG5, "uf_register_netdev: netdev %d - 0x%p\n", interfaceTag, priv->netdev[interfaceTag]); r = register_netdev(priv->netdev[interfaceTag]); if (r) { unifi_error(priv, "Failed to register net device\n"); return -EINVAL; } /* The device is registed */ interfacePriv->netdev_registered = 1; #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) #ifdef CONFIG_NET_SCHED /* * IMPORTANT: * uf_install_qdisc() holds the network device lock, we can not * install the qdisk before the network device is registered. */ r = uf_install_qdisc(priv->netdev[interfaceTag]); if (r) { unifi_error(priv, "Failed to install qdisc\n"); return r; } #endif /* CONFIG_NET_SCHED */ #endif /* LINUX_VERSION_CODE */ #ifdef CSR_SUPPORT_SME /* * Register the inet handler; it notifies us for changes in the IP address. */ uf_register_inet_notifier(); #endif /* CSR_SUPPORT_SME */ unifi_notice(priv, "unifi%d is %s\n", priv->instance, priv->netdev[interfaceTag]->name); return 0; } /* uf_register_netdev */
int unifi_cfg_wmm_addts(unifi_priv_t *priv, unsigned char *arg) { CsrUint32 addts_tid; CsrUint8 addts_ie_length; CsrUint8 *addts_ie; CsrUint8 *addts_params; unifi_DataBlock tspec; unifi_DataBlock tclas; int rc; addts_params = (CsrUint8*)(((unifi_cfg_command_t*)arg) + 1); if (get_user(addts_tid, (CsrUint32*)addts_params)) { unifi_error(priv, "unifi_cfg_wmm_addts: Failed to get the argument\n"); return -EFAULT; } addts_params += sizeof(CsrUint32); if (get_user(addts_ie_length, (CsrUint8*)addts_params)) { unifi_error(priv, "unifi_cfg_wmm_addts: Failed to get the argument\n"); return -EFAULT; } unifi_trace(priv, UDBG4, "addts: tid = 0x%x ie_length = %d\n", addts_tid, addts_ie_length); addts_ie = CsrPmalloc(addts_ie_length); if (addts_ie == NULL) { unifi_error(priv, "unifi_cfg_wmm_addts: Failed to malloc %d bytes for addts_ie buffer\n", addts_ie_length); return -ENOMEM; } addts_params += sizeof(CsrUint8); rc = copy_from_user(addts_ie, addts_params, addts_ie_length); if (rc) { unifi_error(priv, "unifi_cfg_wmm_addts: Failed to get the addts buffer\n"); CsrPfree(addts_ie); return -EFAULT; } tspec.data = addts_ie; tspec.length = addts_ie_length; tclas.data = NULL; tclas.length = 0; rc = sme_mgt_tspec(priv, unifi_ListActionAdd, addts_tid, &tspec, &tclas); CsrPfree(addts_ie); return rc; }
int unifi_cfg_wmm_addts(unifi_priv_t *priv, unsigned char *arg) { u32 addts_tid; u8 addts_ie_length; u8 *addts_ie; u8 *addts_params; CsrWifiSmeDataBlock tspec; CsrWifiSmeDataBlock tclas; int rc; addts_params = (u8*)(((unifi_cfg_command_t*)arg) + 1); if (get_user(addts_tid, (u32*)addts_params)) { unifi_error(priv, "unifi_cfg_wmm_addts: Failed to get the argument\n"); return -EFAULT; } addts_params += sizeof(u32); if (get_user(addts_ie_length, (u8*)addts_params)) { unifi_error(priv, "unifi_cfg_wmm_addts: Failed to get the argument\n"); return -EFAULT; } unifi_trace(priv, UDBG4, "addts: tid = 0x%x ie_length = %d\n", addts_tid, addts_ie_length); addts_ie = kmalloc(addts_ie_length, GFP_KERNEL); if (addts_ie == NULL) { unifi_error(priv, "unifi_cfg_wmm_addts: Failed to malloc %d bytes for addts_ie buffer\n", addts_ie_length); return -ENOMEM; } addts_params += sizeof(u8); rc = copy_from_user(addts_ie, addts_params, addts_ie_length); if (rc) { unifi_error(priv, "unifi_cfg_wmm_addts: Failed to get the addts buffer\n"); kfree(addts_ie); return -EFAULT; } tspec.data = addts_ie; tspec.length = addts_ie_length; tclas.data = NULL; tclas.length = 0; rc = sme_mgt_tspec(priv, CSR_WIFI_SME_LIST_ACTION_ADD, addts_tid, &tspec, &tclas); kfree(addts_ie); return rc; }
void unifi_mgt_mic_failure_ind(void *drvpriv, CsrUint16 appHandlesCount, void* *appHandles, CsrBool secondFailure, CsrUint16 count, const unifi_MACAddress* address, unifi_KeyType keyType, CsrUint16 keyId, const CsrUint16* tSC) { unifi_priv_t *priv = (unifi_priv_t*)drvpriv; CSR_MLME_MICHAELMICFAILURE_INDICATION mic_ind; if (priv == NULL) { unifi_error(NULL, "unifi_mgt_mic_failure_ind: invalid priv\n"); return; } unifi_trace(priv, UDBG1, "unifi_mgt_mic_failure_ind: count=%d, KeyType=%d, KeyId=%d\n", count, keyType, keyId); mic_ind.Count = count; memcpy(mic_ind.Address.x, address->data, 6); mic_ind.KeyType = keyType; mic_ind.KeyId = keyId; memcpy(mic_ind.Tsc, tSC, sizeof(CsrUint16) * 4); wext_send_michaelmicfailure_event(priv, &mic_ind); }
int sme_mgt_connect(unifi_priv_t *priv) { int r; if (priv->smepriv == NULL) { unifi_error(priv, "sme_mgt_connect: invalid smepriv\n"); return -EIO; } unifi_trace(priv, UDBG2, "sme_mgt_connect: %.*s\n", priv->connection_config.ssid.length, priv->connection_config.ssid.ssid); r = sme_init_request(priv); if (r) { return -EIO; } CsrWifiSmeConnectReqSend(0, CSR_WIFI_INTERFACE_IN_USE, priv->connection_config); r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); if (r) { return r; } if (priv->sme_reply.reply_status) { unifi_trace(priv, UDBG1, "sme_mgt_connect: failed with SME status %d\n", priv->sme_reply.reply_status); } return convert_sme_error(priv->sme_reply.reply_status); }
int unifi_cfg_set_ap_config(unifi_priv_t * priv, unsigned char* arg) { uf_cfg_ap_config_t cfg_ap_config; char *buffer; buffer = ((unsigned char*)arg) + sizeof(unifi_cfg_command_t) + sizeof(unsigned int); if (copy_from_user(&cfg_ap_config, (void*)buffer, sizeof(uf_cfg_ap_config_t))) { unifi_error(priv, "UNIFI_CFG: Failed to get the ap config struct\n"); return -EFAULT; } priv->ap_config.channel = cfg_ap_config.channel; priv->ap_mac_config.dtimPeriod = cfg_ap_config.dtimPeriod; priv->ap_mac_config.beaconInterval = cfg_ap_config.beaconInterval; priv->group_sec_config.apGroupkeyTimeout = cfg_ap_config.groupkeyTimeout; priv->group_sec_config.apStrictGtkRekey = cfg_ap_config.strictGtkRekeyEnabled; priv->group_sec_config.apGmkTimeout = cfg_ap_config.gmkTimeout; priv->group_sec_config.apResponseTimeout = cfg_ap_config.responseTimeout; priv->group_sec_config.apRetransLimit = cfg_ap_config.retransLimit; priv->ap_mac_config.shortSlotTimeEnabled = cfg_ap_config.shortSlotTimeEnabled; priv->ap_mac_config.ctsProtectionType=cfg_ap_config.ctsProtectionType; priv->ap_mac_config.wmmEnabled = cfg_ap_config.wmmEnabled; priv->ap_mac_config.apHtParams.rxStbc=cfg_ap_config.rxStbc; priv->ap_mac_config.apHtParams.rifsModeAllowed=cfg_ap_config.rifsModeAllowed; priv->ap_mac_config.phySupportedBitmap = cfg_ap_config.phySupportedBitmap; priv->ap_mac_config.maxListenInterval=cfg_ap_config.maxListenInterval; priv->ap_mac_config.supportedRatesCount= uf_configure_supported_rates(priv->ap_mac_config.supportedRates, priv->ap_mac_config.phySupportedBitmap); return 0; }
int unifi_cfg_enable_okc(unifi_priv_t *priv, unsigned char *arg) { u8 enable_okc; u8 *enable_okc_params; int rc; CsrWifiSmeStaConfig staConfig; CsrWifiSmeDeviceConfig deviceConfig; enable_okc_params = (u8*)(((unifi_cfg_command_t*)arg) + 1); if (get_user(enable_okc, (u8*)enable_okc_params)) { unifi_error(priv, "unifi_cfg_enable_okc: Failed to get the argument\n"); return -EFAULT; } unifi_trace(priv, UDBG4, "enable_okc: = %s\n", ((enable_okc) ? "yes":"no")); rc = sme_mgt_sme_config_get(priv, &staConfig, &deviceConfig); if (rc) { unifi_warning(priv, "unifi_cfg_enable_okc: Get unifi_SMEConfigValue failed.\n"); return -EFAULT; } staConfig.enableOpportunisticKeyCaching = enable_okc; rc = sme_mgt_sme_config_set(priv, &staConfig, &deviceConfig); if (rc) { unifi_warning(priv, "unifi_cfg_enable_okc: Set unifi_SMEConfigValue failed.\n"); rc = -EFAULT; } return rc; }
int unifi_cfg_strict_draft_n(unifi_priv_t *priv, unsigned char *arg) { u8 strict_draft_n; u8 *strict_draft_n_params; int rc; CsrWifiSmeStaConfig staConfig; CsrWifiSmeDeviceConfig deviceConfig; strict_draft_n_params = (u8*)(((unifi_cfg_command_t*)arg) + 1); if (get_user(strict_draft_n, (u8*)strict_draft_n_params)) { unifi_error(priv, "unifi_cfg_strict_draft_n: Failed to get the argument\n"); return -EFAULT; } unifi_trace(priv, UDBG4, "strict_draft_n: = %s\n", ((strict_draft_n) ? "yes":"no")); rc = sme_mgt_sme_config_get(priv, &staConfig, &deviceConfig); if (rc) { unifi_warning(priv, "unifi_cfg_strict_draft_n: Get unifi_SMEConfigValue failed.\n"); return -EFAULT; } deviceConfig.enableStrictDraftN = strict_draft_n; rc = sme_mgt_sme_config_set(priv, &staConfig, &deviceConfig); if (rc) { unifi_warning(priv, "unifi_cfg_strict_draft_n: Set unifi_SMEConfigValue failed.\n"); rc = -EFAULT; } return rc; }
/* * --------------------------------------------------------------------------- * unifi_send_signal * * Invokes send_signal() to queue a signal in the command or traffic queue * If sigptr pointer is NULL, it pokes the bh to check if UniFi is responsive. * * Arguments: * card Pointer to card context struct * sigptr Pointer to signal from card. * siglen Size of the signal * bulkdata Pointer to the bulk data of the signal * * Returns: * CSR_RESULT_SUCCESS on success * CSR_WIFI_HIP_RESULT_NO_SPACE if there were insufficient data slots or no free signal queue entry * * Notes: * unifi_send_signal() is used to queue signals, created by the driver, * to the device. Signals are constructed using the UniFi packed structures. * --------------------------------------------------------------------------- */ CsrResult unifi_send_signal(card_t *card, const CsrUint8 *sigptr, CsrUint32 siglen, const bulk_data_param_t *bulkdata) { q_t *sig_soft_q; CsrUint16 signal_id; CsrResult r; CsrUint32 run_bh; CsrUint32 priority_q; /* A NULL signal pointer is a request to check if UniFi is responsive */ if (sigptr == NULL) { card->bh_reason_host = 1; return unifi_run_bh(card->ospriv); } priority_q = 0; run_bh = 1; signal_id = GET_SIGNAL_ID(sigptr); /* * If the signal is a CSR_MA_PACKET_REQUEST , * we send it using the traffic soft queue. Else we use the command soft queue. */ if (signal_id == CSR_MA_PACKET_REQUEST_ID) { CsrUint16 frame_priority; if (card->periodic_wake_mode == UNIFI_PERIODIC_WAKE_HOST_ENABLED) { run_bh = 0; } #if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE) unifi_debug_log_to_buf("D"); #endif /* Sanity check: MA-PACKET.req must have a valid bulk data */ if ((bulkdata->d[0].data_length == 0) || (bulkdata->d[0].os_data_ptr == NULL)) { unifi_error(card->ospriv, "MA-PACKET.req with empty bulk data (%d bytes in %p)\n", bulkdata->d[0].data_length, bulkdata->d[0].os_data_ptr); dump((void *)sigptr, siglen); return CSR_RESULT_FAILURE; } /* Map the frame priority to a traffic queue index. */ frame_priority = GET_PACKED_MA_PACKET_REQUEST_FRAME_PRIORITY(sigptr); priority_q = unifi_frame_priority_to_queue((CSR_PRIORITY)frame_priority); sig_soft_q = &card->fh_traffic_queue[priority_q]; } else { sig_soft_q = &card->fh_command_queue; } r = send_signal(card, sigptr, siglen, bulkdata, sig_soft_q, priority_q, run_bh); /* On error, the caller must free or requeue bulkdata buffers */ return r; } /* unifi_send_signal() */
int sme_mgt_mib_get(unifi_priv_t *priv, unsigned char *varbind, int *length) { int r; if (priv->smepriv == NULL) { unifi_error(priv, "sme_mgt_mib_get: invalid smepriv\n"); return -EIO; } r = sme_init_request(priv); if (r) { return -EIO; } priv->mib_cfm_buffer = varbind; priv->mib_cfm_buffer_length = MAX_VARBIND_LENGTH; CsrWifiSmeMibGetReqSend(0, *length, varbind); r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); if (r) { priv->mib_cfm_buffer_length = 0; priv->mib_cfm_buffer = NULL; return r; } *length = priv->mib_cfm_buffer_length; priv->mib_cfm_buffer_length = 0; priv->mib_cfm_buffer = NULL; unifi_trace(priv, UDBG4, "sme_mgt_mib_get: <-- (status=%d)\n", priv->sme_reply.reply_status); return convert_sme_error(priv->sme_reply.reply_status); }
int sme_mgt_wifi_off(unifi_priv_t *priv) { int r; if (priv->smepriv == NULL) { unifi_error(priv, "sme_mgt_wifi_off: invalid smepriv\n"); return -EIO; } r = sme_init_request(priv); if (r) { return -EIO; } /* Stop the SME */ CsrWifiSmeWifiOffReqSend(0); r = sme_wait_for_reply(priv, UNIFI_SME_MGT_LONG_TIMEOUT); if (r) { return r; } unifi_trace(priv, UDBG4, "sme_mgt_wifi_off: unifi_mgt_wifi_off_req <-- (r=%d, status=%d)\n", r, priv->sme_reply.reply_status); return convert_sme_error(priv->sme_reply.reply_status); } /* sme_mgt_wifi_off */
int sme_mgt_pmkid(unifi_priv_t *priv, CsrWifiSmeListAction action, CsrWifiSmePmkidList *pmkid_list) { int r; if (priv->smepriv == NULL) { unifi_error(priv, "sme_mgt_pmkid: invalid smepriv\n"); return -EIO; } r = sme_init_request(priv); if (r) { return -EIO; } CsrWifiSmePmkidReqSend(0, CSR_WIFI_INTERFACE_IN_USE, action, pmkid_list->pmkidsCount, pmkid_list->pmkids); r = sme_wait_for_reply(priv, UNIFI_SME_MGT_SHORT_TIMEOUT); if (r) { return r; } unifi_trace(priv, UDBG4, "sme_mgt_pmkid: <-- (status=%d)\n", priv->sme_reply.reply_status); return convert_sme_error(priv->sme_reply.reply_status); }
void uf_sme_cancel_request(unifi_priv_t *priv, CsrResult reply_status) { /* Check for a blocking SME request in progress, and cancel the wait. * This should be used when the character device is closed. */ if (priv == NULL) { unifi_error(priv, "sme_cancel_request: Invalid priv\n"); return; } /* If no request is pending, nothing to wake up */ if (priv->sme_reply.request_status != SME_REQUEST_PENDING) { unifi_trace(priv, UDBG5, "sme_cancel_request: no request was pending (s:%d)\n", priv->sme_reply.request_status); /* Nothing to do */ return; } unifi_trace(priv, UDBG5, "sme_cancel_request: request cancelled (s:%d)\n", priv->sme_reply.request_status); /* Wake up the wait with an error status */ priv->sme_reply.request_status = SME_REQUEST_CANCELLED; priv->sme_reply.reply_status = reply_status; /* unimportant since the CANCELLED state will fail the ioctl */ wake_up_interruptible(&priv->sme_request_wq); return; }
void uf_sme_complete_request(unifi_priv_t *priv, CsrResult reply_status, const char *func) { if (priv == NULL) { unifi_error(priv, "sme_complete_request: Invalid priv\n"); return; } if (priv->sme_reply.request_status != SME_REQUEST_PENDING) { unifi_notice(priv, "sme_complete_request: request not pending %s (s:%d)\n", (func ? func : ""), priv->sme_reply.request_status); return; } unifi_trace(priv, UDBG5, "sme_complete_request: completed %s (s:%d)\n", (func ? func : ""), priv->sme_reply.request_status); priv->sme_reply.request_status = SME_REQUEST_RECEIVED; priv->sme_reply.reply_status = reply_status; wake_up_interruptible(&priv->sme_request_wq); return; }
static CsrResult signal_buffer_init(unifi_priv_t * priv, int size) { int i; priv->rxSignalBuffer.writePointer = priv->rxSignalBuffer.readPointer = 0; priv->rxSignalBuffer.size = size; /* Allocating Memory for Signal primitive pointer */ for(i=0; i<size; i++) { priv->rxSignalBuffer.rx_buff[i].sig_len=0; priv->rxSignalBuffer.rx_buff[i].bufptr = kmalloc(UNIFI_PACKED_SIGBUF_SIZE, GFP_KERNEL); if (priv->rxSignalBuffer.rx_buff[i].bufptr == NULL) { int j; unifi_error(priv,"signal_buffer_init:Failed to Allocate shared memory for T-H signals \n"); for(j=0;j<i;j++) { priv->rxSignalBuffer.rx_buff[j].sig_len=0; kfree(priv->rxSignalBuffer.rx_buff[j].bufptr); priv->rxSignalBuffer.rx_buff[j].bufptr = NULL; } return -1; } } return 0; }
int unifi_putest_start(unifi_priv_t *priv, unsigned char *arg) { int r; CsrInt32 csr_r; int already_in_test = priv->ptest_mode; /* Ensure that sme_sys_suspend() doesn't power down the chip because: * 1) Power is needed anyway for ptest. * 2) The app code uses the START ioctl as a reset, so it gets called * multiple times. If the app stops the XAPs, but the power_down/up * sequence doesn't actually power down the chip, there can be problems * resetting, because part of the power_up sequence disables function 1 */ priv->ptest_mode = 1; /* Suspend the SME and UniFi */ r = sme_sys_suspend(priv); if (r) { unifi_error(priv, "unifi_putest_start: failed to suspend UniFi\n"); return r; } /* Application may have stopped the XAPs, but they are needed for reset */ if (already_in_test) { csr_r = unifi_start_processors(priv->card); if (csr_r) { unifi_error(priv, "Failed to start XAPs. Hard reset required.\n"); } } else { /* Ensure chip is powered for the case where there's no unifi_helper */ csr_r = CsrSdioPowerOn(priv->sdio); if (csr_r) { unifi_error(priv, "CsrSdioPowerOn status %d\n", csr_r); } } csr_r = unifi_init(priv->card); if (csr_r && (csr_r != 1)) { unifi_error(priv, "unifi_putest_start: failed to init UniFi\n"); return convert_csr_error(csr_r); } return 0; }
int unifi_putest_cmd52_write(unifi_priv_t *priv, unsigned char *arg) { struct unifi_putest_cmd52 cmd52_params; CsrUint8 *arg_pos; unsigned int cmd_param_size; CsrInt32 csr_r; arg_pos = (CsrUint8*)(((unifi_putest_command_t*)arg) + 1); if (get_user(cmd_param_size, (int*)arg_pos)) { unifi_error(priv, "unifi_putest_cmd52_write: Failed to get the argument\n"); return -EFAULT; } if (cmd_param_size != sizeof(struct unifi_putest_cmd52)) { unifi_error(priv, "unifi_putest_cmd52_write: cmd52 struct mismatch\n"); return -EINVAL; } arg_pos += sizeof(unsigned int); if (copy_from_user(&cmd52_params, (void*)(arg_pos), sizeof(struct unifi_putest_cmd52))) { unifi_error(priv, "unifi_putest_cmd52_write: Failed to get the cmd52 params\n"); return -EFAULT; } unifi_trace(priv, UDBG2, "cmd52w: func=%d addr=0x%x data=%d\n", cmd52_params.funcnum, cmd52_params.addr, cmd52_params.data); if (cmd52_params.funcnum == 0) { csr_r = CsrSdioF0Write8(priv->sdio, cmd52_params.addr, cmd52_params.data); } else { csr_r = CsrSdioWrite8(priv->sdio, cmd52_params.addr, cmd52_params.data); } if (csr_r) { unifi_error(priv, "unifi_putest_cmd52_write: unifi_sdio_writeb() failed (r=0x%x)\n", csr_r); } return convert_csr_error(csr_r); }
int unifi_cfg_power_save(unifi_priv_t *priv, unsigned char *arg) { unifi_cfg_powersave_t cfg_power_save; unifi_AppValue sme_app_value; int rc; if (get_user(cfg_power_save, (unifi_cfg_powersave_t*)(((unifi_cfg_command_t*)arg) + 1))) { unifi_error(priv, "UNIFI_CFG: Failed to get the argument\n"); return -EFAULT; } /* Get the coex info from the SME */ sme_app_value.id = unifi_PowerConfigValue; rc = sme_mgt_get_value(priv, &sme_app_value); if (rc) { unifi_error(priv, "UNIFI_CFG: Get unifi_PowerConfigValue failed.\n"); return rc; } switch (cfg_power_save) { case UNIFI_CFG_POWERSAVE_NONE: sme_app_value.unifi_Value_union.powerConfig.powerSaveLevel = unifi_PowerSaveLow; break; case UNIFI_CFG_POWERSAVE_FAST: sme_app_value.unifi_Value_union.powerConfig.powerSaveLevel = unifi_PowerSaveMed; break; case UNIFI_CFG_POWERSAVE_FULL: sme_app_value.unifi_Value_union.powerConfig.powerSaveLevel = unifi_PowerSaveHigh; break; case UNIFI_CFG_POWERSAVE_AUTO: sme_app_value.unifi_Value_union.powerConfig.powerSaveLevel = unifi_PowerSaveAuto; break; default: unifi_error(priv, "POWERSAVE: Unknown value.\n"); return -EINVAL; } sme_app_value.id = unifi_PowerConfigValue; rc = sme_mgt_set_value(priv, &sme_app_value); if (rc) { unifi_error(priv, "UNIFI_CFG: Set unifi_PowerConfigValue failed.\n"); } return rc; }
int unifi_cfg_power_save(unifi_priv_t *priv, unsigned char *arg) { unifi_cfg_powersave_t cfg_power_save; CsrWifiSmePowerConfig powerConfig; int rc; if (get_user(cfg_power_save, (unifi_cfg_powersave_t*)(((unifi_cfg_command_t*)arg) + 1))) { unifi_error(priv, "UNIFI_CFG: Failed to get the argument\n"); return -EFAULT; } /* Get the coex info from the SME */ rc = sme_mgt_power_config_get(priv, &powerConfig); if (rc) { unifi_error(priv, "UNIFI_CFG: Get unifi_PowerConfigValue failed.\n"); return rc; } switch (cfg_power_save) { case UNIFI_CFG_POWERSAVE_NONE: powerConfig.powerSaveLevel = CSR_WIFI_SME_POWER_SAVE_LEVEL_LOW; break; case UNIFI_CFG_POWERSAVE_FAST: powerConfig.powerSaveLevel = CSR_WIFI_SME_POWER_SAVE_LEVEL_MED; break; case UNIFI_CFG_POWERSAVE_FULL: powerConfig.powerSaveLevel = CSR_WIFI_SME_POWER_SAVE_LEVEL_HIGH; break; case UNIFI_CFG_POWERSAVE_AUTO: powerConfig.powerSaveLevel = CSR_WIFI_SME_POWER_SAVE_LEVEL_AUTO; break; default: unifi_error(priv, "POWERSAVE: Unknown value.\n"); return -EINVAL; } rc = sme_mgt_power_config_set(priv, &powerConfig); if (rc) { unifi_error(priv, "UNIFI_CFG: Set unifi_PowerConfigValue failed.\n"); } return rc; }
int sme_queue_message(unifi_priv_t *priv, u8 *buffer, int length) { ul_client_t *pcli; udi_log_t *logptr; udi_msg_t *msgptr; u8 *p; func_enter(); /* Just a sanity check */ if ((buffer == NULL) || (length <= 0)) { return -EINVAL; } pcli = priv->sme_cli; if (pcli == NULL) { CsrPfree(buffer); return -EINVAL; } /* Allocate log structure plus actual signal. */ logptr = (udi_log_t *)kmalloc(sizeof(udi_log_t) + length, GFP_KERNEL); if (logptr == NULL) { unifi_error(priv, "Failed to allocate %d bytes for an SME message\n", sizeof(udi_log_t) + length); CsrPfree(buffer); return -ENOMEM; } /* Fill in udi_log struct */ INIT_LIST_HEAD(&logptr->q); msgptr = &logptr->msg; msgptr->length = sizeof(udi_msg_t) + length; msgptr->signal_length = length; /* Copy signal and bulk data to the log */ p = (u8 *)(msgptr + 1); memcpy(p, buffer, length); /* Add to tail of log queue */ down(&pcli->udi_sem); list_add_tail(&logptr->q, &pcli->udi_log); up(&pcli->udi_sem); /* Wake any waiting user process */ wake_up_interruptible(&pcli->udi_wq); /* It is our responsibility to free the buffer allocated in build_packed_*() */ CsrPfree(buffer); func_exit(); return 0; } /* sme_queue_message() */
void unifi_mgt_mib_set_cfm(void *drvpriv, void* appHandle, unifi_Status status) { unifi_priv_t *priv = (unifi_priv_t*)drvpriv; if (priv == NULL) { unifi_error(NULL, "unifi_mgt_mib_set_cfm: Invalid ospriv.\n"); return; } sme_complete_request(priv, status); }
void unifi_mgt_packet_filter_set_cfm(void *drvpriv, void* appHandle, unifi_Status status) { unifi_priv_t *priv = (unifi_priv_t*)drvpriv; if (priv == NULL) { unifi_error(NULL, "unifi_mgt_packet_filter_set_cfm: Invalid ospriv.\n"); return; } /* The packet filter set request does not block for a reply */ }
void uf_multicast_list_wq(struct work_struct *work) { unifi_priv_t *priv = container_of(work, unifi_priv_t, multicast_list_task); int i; u16 interfaceTag = 0; CsrWifiMacAddress* multicast_address_list = NULL; int mc_count; u8 *mc_list; netInterface_priv_t *interfacePriv = priv->interfacePriv[interfaceTag]; if (interfaceTag >= CSR_WIFI_NUM_INTERFACES) { unifi_error(priv, "uf_multicast_list_wq: bad interfaceTag\n"); return; } unifi_trace(priv, UDBG5, "uf_multicast_list_wq: list count = %d\n", interfacePriv->mc_list_count); /* Flush the current list */ CsrWifiRouterCtrlMulticastAddressIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, 0, interfaceTag, CSR_WIFI_SME_LIST_ACTION_FLUSH, 0, NULL); mc_count = interfacePriv->mc_list_count; mc_list = interfacePriv->mc_list; /* * Allocate a new list, need to free it later * in unifi_mgt_multicast_address_cfm(). */ multicast_address_list = kmalloc(mc_count * sizeof(CsrWifiMacAddress), GFP_KERNEL); if (multicast_address_list == NULL) { return; } for (i = 0; i < mc_count; i++) { memcpy(multicast_address_list[i].a, mc_list, ETH_ALEN); mc_list += ETH_ALEN; } if (priv->smepriv == NULL) { kfree(multicast_address_list); return; } CsrWifiRouterCtrlMulticastAddressIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, 0, interfaceTag, CSR_WIFI_SME_LIST_ACTION_ADD, mc_count, multicast_address_list); /* The SME will take a copy of the addreses*/ kfree(multicast_address_list); }
void uf_add_os_device(int bus_id, struct device *os_device) { if ((bus_id < 0) || (bus_id >= MAX_UNIFI_DEVS)) { unifi_error(NULL, "uf_add_os_device: invalid device %d\n", bus_id); return; } active_slot = bus_id; os_devices[bus_id] = os_device; } /* uf_add_os_device() */
void uf_remove_os_device(int bus_id) { if ((bus_id < 0) || (bus_id >= MAX_UNIFI_DEVS)) { unifi_error(NULL, "uf_remove_os_device: invalid device %d\n", bus_id); return; } active_slot = bus_id; os_devices[bus_id] = NULL; } /* uf_remove_os_device() */
int unifi_cfg_power(unifi_priv_t *priv, unsigned char *arg) { unifi_cfg_power_t cfg_power; int rc; int wol; if (get_user(cfg_power, (unifi_cfg_power_t*)(((unifi_cfg_command_t*)arg) + 1))) { unifi_error(priv, "UNIFI_CFG: Failed to get the argument\n"); return -EFAULT; } switch (cfg_power) { case UNIFI_CFG_POWER_OFF: priv->wol_suspend = (enable_wol == UNIFI_WOL_OFF) ? FALSE : TRUE; rc = sme_sys_suspend(priv); if (rc) { return rc; } break; case UNIFI_CFG_POWER_ON: wol = priv->wol_suspend; rc = sme_sys_resume(priv); if (rc) { return rc; } if (wol) { /* Kick the BH to ensure pending transfers are handled when * a suspend happened with card powered. */ unifi_send_signal(priv->card, NULL, 0, NULL); } break; default: unifi_error(priv, "WIFI POWER: Unknown value.\n"); return -EINVAL; } return 0; }