diff options
Diffstat (limited to 'drivers/staging/csr/unifi_sme.c')
-rw-r--r-- | drivers/staging/csr/unifi_sme.c | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/drivers/staging/csr/unifi_sme.c b/drivers/staging/csr/unifi_sme.c index 4ee663fe4e4a..54414ed2ed1c 100644 --- a/drivers/staging/csr/unifi_sme.c +++ b/drivers/staging/csr/unifi_sme.c @@ -447,6 +447,7 @@ 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"); @@ -455,16 +456,24 @@ int unifi_cfg_power(unifi_priv_t *priv, unsigned char *arg) 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"); @@ -921,10 +930,19 @@ int supportedRates[i++]=0x8b; supportedRates[i++]=0x96; } else if(n) { + /* For some strange reasons WiFi stack needs both b and g rates*/ supportedRates[i++]=0x02; supportedRates[i++]=0x04; supportedRates[i++]=0x0b; supportedRates[i++]=0x16; + supportedRates[i++]=0x0c; + supportedRates[i++]=0x12; + supportedRates[i++]=0x18; + supportedRates[i++]=0x24; + supportedRates[i++]=0x30; + supportedRates[i++]=0x48; + supportedRates[i++]=0x60; + supportedRates[i++]=0x6c; } if(g) { if(!b) { @@ -1162,3 +1180,65 @@ uf_send_m4_ready_wq(struct work_struct *work) } /* uf_send_m4_ready_wq() */ +#if (defined(CSR_WIFI_SECURITY_WAPI_ENABLE) && defined(CSR_WIFI_SECURITY_WAPI_SW_ENCRYPTION)) +/* + * --------------------------------------------------------------------------- + * uf_send_pkt_to_encrypt + * + * Deferred work queue function to send the WAPI data pkts to SME when unicast KeyId = 1 + * These are done in a deferred work queue for two reasons: + * - the CsrWifiRouterCtrl...Send() functions are not safe for atomic context + * - we want to load the main driver data path as lightly as possible + * + * Arguments: + * work Pointer to work queue item. + * + * Returns: + * None. + * --------------------------------------------------------------------------- + */ +void uf_send_pkt_to_encrypt(struct work_struct *work) +{ + netInterface_priv_t *interfacePriv = container_of(work, netInterface_priv_t, send_pkt_to_encrypt); + CsrUint16 interfaceTag = interfacePriv->InterfaceTag; + unifi_priv_t *priv = interfacePriv->privPtr; + + CsrUint32 pktBulkDataLength; + CsrUint8 *pktBulkData; + unsigned long flags; + + if (interfacePriv->interfaceMode == CSR_WIFI_ROUTER_CTRL_MODE_STA) { + + func_enter(); + + pktBulkDataLength = interfacePriv->wapi_unicast_bulk_data.data_length; + + if (pktBulkDataLength > 0) { + pktBulkData = (CsrUint8 *)CsrPmemAlloc(pktBulkDataLength); + CsrMemSet(pktBulkData, 0, pktBulkDataLength); + } else { + unifi_error(priv, "uf_send_pkt_to_encrypt() : invalid buffer\n"); + return; + } + + spin_lock_irqsave(&priv->wapi_lock, flags); + /* Copy over the MA PKT REQ bulk data */ + CsrMemCpy(pktBulkData, (CsrUint8*)interfacePriv->wapi_unicast_bulk_data.os_data_ptr, pktBulkDataLength); + /* Free any bulk data buffers allocated for the WAPI Data pkt */ + unifi_net_data_free(priv, &interfacePriv->wapi_unicast_bulk_data); + interfacePriv->wapi_unicast_bulk_data.net_buf_length = 0; + interfacePriv->wapi_unicast_bulk_data.data_length = 0; + interfacePriv->wapi_unicast_bulk_data.os_data_ptr = interfacePriv->wapi_unicast_bulk_data.os_net_buf_ptr = NULL; + spin_unlock_irqrestore(&priv->wapi_lock, flags); + + CsrWifiRouterCtrlWapiUnicastTxEncryptIndSend(priv->CSR_WIFI_SME_IFACEQUEUE, 0, interfaceTag, pktBulkDataLength, pktBulkData); + unifi_trace(priv, UDBG1, "WapiUnicastTxEncryptInd sent to SME\n"); + + CsrPmemFree(pktBulkData); /* Would have been copied over by the SME Handler */ + + func_exit(); + } else { + unifi_warning(priv, "uf_send_pkt_to_encrypt() is NOT applicable for interface mode - %d\n",interfacePriv->interfaceMode); + } +}/* uf_send_pkt_to_encrypt() */ +#endif |