Пример #1
0
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);
}
Пример #2
0
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;
}
Пример #3
0
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;
}
Пример #4
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
}
Пример #5
0
/*
 * ---------------------------------------------------------------------------
 *  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 */
Пример #6
0
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;
}
Пример #7
0
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;
}
Пример #8
0
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);
}
Пример #9
0
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);
}
Пример #10
0
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;
}
Пример #11
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;
}
Пример #12
0
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() */
Пример #14
0
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);
}
Пример #15
0
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 */
Пример #16
0
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);
}
Пример #17
0
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;
}
Пример #18
0
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;
}
Пример #19
0
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;
}
Пример #20
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;
}
Пример #21
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);
}
Пример #22
0
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;
}
Пример #23
0
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;
}
Пример #24
0
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() */
Пример #25
0
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);
}
Пример #26
0
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 */
}
Пример #27
0
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);
}
Пример #28
0
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() */
Пример #29
0
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() */
Пример #30
0
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;
}