static int orinoco_scan(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_scan_request *request) { struct orinoco_private *priv = wiphy_priv(wiphy); int err; if (!request) return -EINVAL; if (priv->scan_request && priv->scan_request != request) return -EBUSY; priv->scan_request = request; err = orinoco_hw_trigger_scan(priv, request->ssids); /* On error the we aren't processing the request */ if (err) priv->scan_request = NULL; return err; }
static int orinoco_set_channel(struct wiphy *wiphy, struct net_device *netdev, struct ieee80211_channel *chan, enum nl80211_channel_type channel_type) { struct orinoco_private *priv = wiphy_priv(wiphy); int err = 0; unsigned long flags; int channel; if (!chan) return -EINVAL; if (channel_type != NL80211_CHAN_NO_HT) return -EINVAL; if (chan->band != IEEE80211_BAND_2GHZ) return -EINVAL; channel = ieee80211_freq_to_dsss_chan(chan->center_freq); if ((channel < 1) || (channel > NUM_CHANNELS) || !(priv->channel_mask & (1 << (channel - 1)))) return -EINVAL; if (orinoco_lock(priv, &flags) != 0) return -EBUSY; priv->channel = channel; if (priv->iw_mode == NL80211_IFTYPE_MONITOR) { struct hermes *hw = &priv->hw; err = hw->ops->cmd_wait(hw, HERMES_CMD_TEST | HERMES_TEST_SET_CHANNEL, channel, NULL); } orinoco_unlock(priv, &flags); return err; }
int mtk_cfg80211_testmode_cmd(IN struct wiphy *wiphy, IN void *data, IN int len) { P_GLUE_INFO_T prGlueInfo = NULL; P_NL80211_DRIVER_TEST_MODE_PARAMS prParams = (P_NL80211_DRIVER_TEST_MODE_PARAMS) NULL; BOOLEAN fgIsValid = 0; ASSERT(wiphy); prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); #if 1 printk("--> %s()\n", __func__); #endif if (data && len) prParams = (P_NL80211_DRIVER_TEST_MODE_PARAMS) data; /* Clear the version byte */ prParams->index = prParams->index & ~BITS(24, 31); if (prParams) { switch (prParams->index) { case 1: /* SW cmd */ if (mtk_cfg80211_testmode_sw_cmd(wiphy, data, len)) fgIsValid = TRUE; break; case 2: /* WAPI */ #if CFG_SUPPORT_WAPI if (mtk_cfg80211_testmode_set_key_ext(wiphy, data, len)) fgIsValid = TRUE; #endif break; default: fgIsValid = TRUE; break; } } return fgIsValid; }
/*----------------------------------------------------------------------------*/ int mtk_cfg80211_flush_pmksa ( struct wiphy *wiphy, struct net_device *ndev ) { P_GLUE_INFO_T prGlueInfo = NULL; WLAN_STATUS rStatus; UINT_32 u4BufLen; P_PARAM_PMKID_T prPmkid; prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ASSERT(prGlueInfo); prPmkid =(P_PARAM_PMKID_T)kalMemAlloc(8, VIR_MEM_TYPE); if (!prPmkid) { DBGLOG(INIT, INFO, ("Can not alloc memory for IW_PMKSA_FLUSH\n")); return -ENOMEM; } prPmkid->u4Length = 8; prPmkid->u4BSSIDInfoCount = 0; rStatus = kalIoctl(prGlueInfo, wlanoidSetPmkid, prPmkid, sizeof(PARAM_PMKID_T), FALSE, FALSE, FALSE, FALSE, &u4BufLen); if (rStatus != WLAN_STATUS_SUCCESS) { DBGLOG(INIT, INFO, ("flush pmkid error:%lx\n", rStatus)); } kalMemFree(prPmkid, VIR_MEM_TYPE, 8); return 0; }
static void qtnf_cfg80211_reg_notifier(struct wiphy *wiphy_in, struct regulatory_request *req) { struct qtnf_wmac *mac = wiphy_priv(wiphy_in); struct qtnf_bus *bus = mac->bus; struct wiphy *wiphy; unsigned int mac_idx; enum nl80211_band band; int ret; pr_debug("MAC%u: initiator=%d alpha=%c%c\n", mac->macid, req->initiator, req->alpha2[0], req->alpha2[1]); ret = qtnf_cmd_reg_notify(bus, req); if (ret) { if (ret != -EOPNOTSUPP && ret != -EALREADY) pr_err("failed to update reg domain to %c%c\n", req->alpha2[0], req->alpha2[1]); return; } for (mac_idx = 0; mac_idx < QTNF_MAX_MAC; ++mac_idx) { if (!(bus->hw_info.mac_bitmap & (1 << mac_idx))) continue; mac = bus->mac[mac_idx]; wiphy = priv_to_wiphy(mac); for (band = 0; band < NUM_NL80211_BANDS; ++band) { if (!wiphy->bands[band]) continue; ret = qtnf_cmd_get_mac_chan_info(mac, wiphy->bands[band]); if (ret) pr_err("failed to get chan info for mac %u band %u\n", mac_idx, band); } } }
static int qtnf_get_channel(struct wiphy *wiphy, struct wireless_dev *wdev, struct cfg80211_chan_def *chandef) { struct qtnf_wmac *mac = wiphy_priv(wiphy); struct net_device *ndev = wdev->netdev; struct qtnf_vif *vif; if (!ndev) return -ENODEV; vif = qtnf_netdev_get_priv(wdev->netdev); switch (vif->wdev.iftype) { case NL80211_IFTYPE_STATION: if (vif->sta_state == QTNF_STA_DISCONNECTED) { pr_warn("%s: STA disconnected\n", ndev->name); return -ENODATA; } break; case NL80211_IFTYPE_AP: if (!(vif->bss_status & QTNF_STATE_AP_START)) { pr_warn("%s: AP not started\n", ndev->name); return -ENODATA; } break; default: pr_err("unsupported vif type (%d)\n", vif->wdev.iftype); return -ENODATA; } if (!cfg80211_chandef_valid(&mac->chandef)) { pr_err("invalid channel settings on %s\n", ndev->name); return -ENODATA; } memcpy(chandef, &mac->chandef, sizeof(*chandef)); return 0; }
static int r92su_add_key(struct wiphy *wiphy, struct net_device *ndev, u8 idx, bool pairwise, const u8 *mac_addr, struct key_params *params) { struct r92su *r92su = wiphy_priv(wiphy); int err; struct cfg80211_bss *bss; mutex_lock(&r92su->lock); if (!r92su_is_connected(r92su)) { err = -EAGAIN; goto out_unlock; } bss = rcu_dereference_protected(r92su->connect_bss, lockdep_is_held(&r92su->lock)); err = r92su_internal_add_key(r92su, bss, params->cipher, idx, pairwise, mac_addr, params->key, false); out_unlock: mutex_unlock(&r92su->lock); return err; }
static int r92su_change_virtual_intf(struct wiphy *wiphy, struct net_device *ndev, enum nl80211_iftype type, u32 *flags, struct vif_params *params) { struct r92su *r92su = wiphy_priv(wiphy); int err = -EAGAIN; mutex_lock(&r92su->lock); if (!r92su_is_stopped(r92su)) goto out; switch (type) { case NL80211_IFTYPE_MONITOR: ndev->type = ARPHRD_IEEE80211_RADIOTAP; break; case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_ADHOC: ndev->type = ARPHRD_ETHER; break; default: err = -EOPNOTSUPP; goto out; } if (r92su_is_open(r92su)) { err = -EBUSY; goto out; } r92su->wdev.iftype = type; err = 0; out: mutex_unlock(&r92su->lock); return err; }
/*----------------------------------------------------------------------------*/ int mtk_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_index, bool pairwise, const u8 *mac_addr, void *cookie, void (*callback) (void *cookie, struct key_params *) ) { P_GLUE_INFO_T prGlueInfo = NULL; prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ASSERT(prGlueInfo); #if 1 printk("--> %s()\n", __func__); #endif /* not implemented */ return -EINVAL; }
/*----------------------------------------------------------------------------*/ int mtk_cfg80211_set_default_key ( struct wiphy *wiphy, struct net_device *ndev, u8 key_index, bool unicast, bool multicast ) { P_GLUE_INFO_T prGlueInfo = NULL; prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ASSERT(prGlueInfo); #if 1 printk("--> %s()\n", __func__); #endif /* not implemented */ return -EINVAL; }
static int orinoco_set_monitor_channel(struct wiphy *wiphy, struct cfg80211_chan_def *chandef) { struct orinoco_private *priv = wiphy_priv(wiphy); int err = 0; unsigned long flags; int channel; if (!chandef->chan) return -EINVAL; if (cfg80211_get_chandef_type(chandef) != NL80211_CHAN_NO_HT) return -EINVAL; if (chandef->chan->band != IEEE80211_BAND_2GHZ) return -EINVAL; channel = ieee80211_frequency_to_channel(chandef->chan->center_freq); if ((channel < 1) || (channel > NUM_CHANNELS) || !(priv->channel_mask & (1 << (channel - 1)))) return -EINVAL; if (orinoco_lock(priv, &flags) != 0) return -EBUSY; priv->channel = channel; if (priv->iw_mode == NL80211_IFTYPE_MONITOR) { /* Fast channel change - no commit if successful */ struct hermes *hw = &priv->hw; err = hw->ops->cmd_wait(hw, HERMES_CMD_TEST | HERMES_TEST_SET_CHANNEL, channel, NULL); } orinoco_unlock(priv, &flags); return err; }
static int qtnf_set_wiphy_params(struct wiphy *wiphy, u32 changed) { struct qtnf_wmac *mac = wiphy_priv(wiphy); struct qtnf_vif *vif; int ret; vif = qtnf_mac_get_base_vif(mac); if (!vif) { pr_err("MAC%u: primary VIF is not configured\n", mac->macid); return -EFAULT; } if (changed & (WIPHY_PARAM_RETRY_LONG | WIPHY_PARAM_RETRY_SHORT)) { pr_err("MAC%u: can't modify retry params\n", mac->macid); return -EOPNOTSUPP; } ret = qtnf_cmd_send_update_phy_params(mac, changed); if (ret) pr_err("MAC%u: failed to update PHY params\n", mac->macid); return ret; }
/*----------------------------------------------------------------------------*/ int mtk_cfg80211_remain_on_channel ( struct wiphy *wiphy, struct net_device *ndev, struct ieee80211_channel *chan, enum nl80211_channel_type channel_type, unsigned int duration, u64 *cookie ) { P_GLUE_INFO_T prGlueInfo = NULL; prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ASSERT(prGlueInfo); #if 1 printk("--> %s()\n", __func__); #endif /* not implemented */ return -EINVAL; }
int wlan_hdd_del_virtual_intf( struct wiphy *wiphy, struct net_device *dev ) { hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy); hdd_adapter_t *pVirtAdapter = WLAN_HDD_GET_PRIV_PTR(dev); ENTER(); hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d", __func__,pVirtAdapter->device_mode); if (pHddCtx->isLogpInProgress) { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:LOGP in Progress. Ignore!!!", __func__); return -EAGAIN; } wlan_hdd_release_intf_addr( pHddCtx, pVirtAdapter->macAddressCurrent.bytes ); hdd_stop_adapter( pHddCtx, pVirtAdapter ); hdd_close_adapter( pHddCtx, pVirtAdapter, TRUE ); EXIT(); return 0; }
/*----------------------------------------------------------------------------*/ int mtk_cfg80211_remain_on_channel(struct wiphy *wiphy, #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0) struct net_device *ndev, #else struct wireless_dev *wdev, #endif struct ieee80211_channel *chan, enum nl80211_channel_type channel_type, unsigned int duration, u64 *cookie) { P_GLUE_INFO_T prGlueInfo = NULL; prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ASSERT(prGlueInfo); #if 1 printk("--> %s()\n", __func__); #endif /* not implemented */ return -EINVAL; }
/* Functions to create/free wiphy interface */ static struct wiphy *wlan_create_wiphy(struct device *dev, struct wlandevice *wlandev) { struct wiphy *wiphy; struct prism2_wiphy_private *priv; wiphy = wiphy_new(&prism2_usb_cfg_ops, sizeof(*priv)); if (!wiphy) return NULL; priv = wiphy_priv(wiphy); priv->wlandev = wlandev; memcpy(priv->channels, prism2_channels, sizeof(prism2_channels)); memcpy(priv->rates, prism2_rates, sizeof(prism2_rates)); priv->band.channels = priv->channels; priv->band.n_channels = ARRAY_SIZE(prism2_channels); priv->band.bitrates = priv->rates; priv->band.n_bitrates = ARRAY_SIZE(prism2_rates); priv->band.band = NL80211_BAND_2GHZ; priv->band.ht_cap.ht_supported = false; wiphy->bands[NL80211_BAND_2GHZ] = &priv->band; set_wiphy_dev(wiphy, dev); wiphy->privid = prism2_wiphy_privid; wiphy->max_scan_ssids = 1; wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; wiphy->n_cipher_suites = PRISM2_NUM_CIPHER_SUITES; wiphy->cipher_suites = prism2_cipher_suites; if (wiphy_register(wiphy) < 0) { wiphy_free(wiphy); return NULL; } return wiphy; }
/*----------------------------------------------------------------------------*/ int mtk_cfg80211_mgmt_tx_cancel_wait ( struct wiphy *wiphy, #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0) struct net_device *ndev, #else struct wireless_device *wdev, #endif u64 cookie ) { P_GLUE_INFO_T prGlueInfo = NULL; prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ASSERT(prGlueInfo); #if 1 printk("--> %s()\n", __func__); #endif /* not implemented */ return -EINVAL; }
/*----------------------------------------------------------------------------*/ int mtk_cfg80211_disconnect ( struct wiphy *wiphy, struct net_device *ndev, u16 reason_code ) { P_GLUE_INFO_T prGlueInfo = NULL; WLAN_STATUS rStatus; UINT_32 u4BufLen; prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ASSERT(prGlueInfo); #if RSSI_ENHANCE initRssiHistory(); initScanRssiHistory(); #endif rStatus = kalIoctl(prGlueInfo, wlanoidSetDisassociate, NULL, 0, FALSE, FALSE, TRUE, FALSE, &u4BufLen); if (rStatus != WLAN_STATUS_SUCCESS) { DBGLOG(REQ, WARN, ("disassociate error:%lx\n", rStatus)); return -EFAULT; } return 0; }
static int wl_cfgvendor_set_pno_mac_oui(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len) { int err = 0; struct wl_priv *cfg = wiphy_priv(wiphy); int type; uint8 pno_random_mac_oui[DOT11_OUI_LEN]; type = nla_type(data); if (type == ANDR_WIFI_ATTRIBUTE_PNO_RANDOM_MAC_OUI) { memcpy(pno_random_mac_oui, nla_data(data), DOT11_OUI_LEN); err = dhd_dev_pno_set_mac_oui(wl_to_prmry_ndev(cfg), pno_random_mac_oui); if (unlikely(err)) WL_ERR(("Bad OUI, could not set:%d \n", err)); } else { err = -1; } return err; }
static int dhd_cfgvendor_priv_string_handler(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len) { const struct bcm_nlmsg_hdr *nlioc = data; struct net_device *ndev = NULL; struct bcm_cfg80211 *cfg; struct sk_buff *reply; void *buf = NULL, *cur; dhd_pub_t *dhd; dhd_ioctl_t ioc = { 0 }; int ret = 0, ret_len, payload, msglen; int maxmsglen = PAGE_SIZE - 0x100; int8 index; WL_TRACE(("entry: cmd = %d\n", nlioc->cmd)); cfg = wiphy_priv(wiphy); dhd = cfg->pub; DHD_OS_WAKE_LOCK(dhd); /* send to dongle only if we are not waiting for reload already */ if (dhd->hang_was_sent) { WL_ERR(("HANG was sent up earlier\n")); DHD_OS_WAKE_LOCK_CTRL_TIMEOUT_ENABLE(dhd, DHD_EVENT_TIMEOUT_MS); DHD_OS_WAKE_UNLOCK(dhd); return OSL_ERROR(BCME_DONGLE_DOWN); } len -= sizeof(struct bcm_nlmsg_hdr); ret_len = nlioc->len; if (ret_len > 0 || len > 0) { if (len > DHD_IOCTL_MAXLEN) { WL_ERR(("oversize input buffer %d\n", len)); len = DHD_IOCTL_MAXLEN; } if (ret_len > DHD_IOCTL_MAXLEN) { WL_ERR(("oversize return buffer %d\n", ret_len)); ret_len = DHD_IOCTL_MAXLEN; } payload = max(ret_len, len) + 1; buf = vzalloc(payload); if (!buf) { DHD_OS_WAKE_UNLOCK(dhd); return -ENOMEM; } memcpy(buf, (void *)nlioc + nlioc->offset, len); *(char *)(buf + len) = '\0'; } ndev = wdev_to_wlc_ndev(wdev, cfg); index = dhd_net2idx(dhd->info, ndev); if (index == DHD_BAD_IF) { WL_ERR(("Bad ifidx from wdev:%p\n", wdev)); ret = BCME_ERROR; goto done; } ioc.cmd = nlioc->cmd; ioc.len = nlioc->len; ioc.set = nlioc->set; ioc.driver = nlioc->magic; ret = dhd_ioctl_process(dhd, index, &ioc, buf); if (ret) { WL_TRACE(("dhd_ioctl_process return err %d\n", ret)); ret = OSL_ERROR(ret); goto done; } cur = buf; while (ret_len > 0) { msglen = nlioc->len > maxmsglen ? maxmsglen : ret_len; ret_len -= msglen; payload = msglen + sizeof(msglen); reply = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, payload); if (!reply) { WL_ERR(("Failed to allocate reply msg\n")); ret = -ENOMEM; break; } if (nla_put(reply, BCM_NLATTR_DATA, msglen, cur) || nla_put_u16(reply, BCM_NLATTR_LEN, msglen)) { kfree_skb(reply); ret = -ENOBUFS; break; } ret = cfg80211_vendor_cmd_reply(reply); if (ret) { WL_ERR(("testmode reply failed:%d\n", ret)); break; } cur += msglen; } done: vfree(buf); DHD_OS_WAKE_UNLOCK(dhd); return ret; }
/*----------------------------------------------------------------------------*/ int mtk_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_ibss_params *params) { PARAM_SSID_T rNewSsid; P_GLUE_INFO_T prGlueInfo = NULL; UINT_32 u4ChnlFreq; /* Store channel or frequency information */ UINT_32 u4BufLen = 0; WLAN_STATUS rStatus; prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ASSERT(prGlueInfo); /* set channel */ #if LINUX_VERSION_CODE <= KERNEL_VERSION(3, 7, 0) if (params->channel) { u4ChnlFreq = nicChannelNum2Freq(params->channel->hw_value); #else if (params->chandef.chan) { u4ChnlFreq = nicChannelNum2Freq(params->chandef.chan->hw_value); #endif rStatus = kalIoctl(prGlueInfo, wlanoidSetFrequency, &u4ChnlFreq, sizeof(u4ChnlFreq), FALSE, FALSE, FALSE, FALSE, &u4BufLen); if (rStatus != WLAN_STATUS_SUCCESS) { return -EFAULT; } } /* set SSID */ kalMemCopy(rNewSsid.aucSsid, params->ssid, params->ssid_len); rStatus = kalIoctl(prGlueInfo, wlanoidSetSsid, (PVOID) & rNewSsid, sizeof(PARAM_SSID_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); if (rStatus != WLAN_STATUS_SUCCESS) { DBGLOG(REQ, WARN, ("set SSID:%lx\n", rStatus)); return -EFAULT; } return 0; return -EINVAL; } /*----------------------------------------------------------------------------*/ /*! * @brief This routine is responsible for requesting to leave from IBSS group * * @param * * @retval 0: successful * others: failure */ /*----------------------------------------------------------------------------*/ int mtk_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev) { P_GLUE_INFO_T prGlueInfo = NULL; WLAN_STATUS rStatus; UINT_32 u4BufLen; prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ASSERT(prGlueInfo); rStatus = kalIoctl(prGlueInfo, wlanoidSetDisassociate, NULL, 0, FALSE, FALSE, TRUE, FALSE, &u4BufLen); if (rStatus != WLAN_STATUS_SUCCESS) { DBGLOG(REQ, WARN, ("disassociate error:%lx\n", rStatus)); return -EFAULT; } return 0; }
static int r92su_connect(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_connect_params *sme) { struct r92su *r92su = wiphy_priv(wiphy); struct cfg80211_bss *bss = NULL; struct r92su_bss_priv *bss_priv = NULL; int err = -ENODEV; u8 ie_buf[256]; u8 *ie = ie_buf; u32 ie_len_left = sizeof(ie_buf); err = r92su_internal_scan(r92su, sme->ssid, sme->ssid_len); if (err) return err; mutex_lock(&r92su->lock); if (!r92su_is_open(r92su)) goto out; bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid, sme->ssid, sme->ssid_len, IEEE80211_BSS_TYPE_ESS, IEEE80211_PRIVACY_ANY); if (!bss) { err = -ENOENT; goto out; } bss_priv = r92su_get_bss_priv(bss); err = r92su_connect_set_auth(r92su, bss, sme->auth_type, &sme->crypto); if (err) goto out; err = r92su_connect_set_shared_key(r92su, bss, sme); if (err) goto out; WARN(!r92su_add_ies(r92su, &ie, &ie_len_left, sme->ie, sme->ie_len), "no space left for cfg80211's ies"); if (!(sme->flags & ASSOC_REQ_DISABLE_HT)) { WARN(!r92su_ht_update(r92su, &ie, &ie_len_left), "no space left for ht caps ie"); } WARN(!r92su_wmm_update(r92su, &ie, &ie_len_left), "no space left for wmm ie"); err = r92su_internal_connect(r92su, bss, true, ie_buf, ie - ie_buf); out: if (err) { if (bss_priv) kfree(bss_priv->assoc_ie); r92su->want_connect_bss = NULL; if (bss) cfg80211_put_bss(wiphy, bss); } mutex_unlock(&r92su->lock); return err; }
int mtk_cfg80211_testmode_set_key_ext( IN struct wiphy *wiphy, IN void *data, IN int len) { P_GLUE_INFO_T prGlueInfo = NULL; P_NL80211_DRIVER_SET_KEY_EXTS prParams = (P_NL80211_DRIVER_SET_KEY_EXTS)NULL; struct iw_encode_exts *prIWEncExt = (struct iw_encode_exts *)NULL; WLAN_STATUS rstatus = WLAN_STATUS_SUCCESS; int fgIsValid = 0; UINT_32 u4BufLen = 0; P_PARAM_WPI_KEY_T prWpiKey = (P_PARAM_WPI_KEY_T) keyStructBuf; memset(keyStructBuf, 0, sizeof(keyStructBuf)); ASSERT(wiphy); prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); #if 1 printk("--> %s()\n", __func__); #endif if(data && len) { prParams = (P_NL80211_DRIVER_SET_KEY_EXTS)data; } if(prParams) { prIWEncExt = (struct iw_encode_exts *) &prParams->ext; } if (prIWEncExt->alg == IW_ENCODE_ALG_SMS4) { /* KeyID */ prWpiKey->ucKeyID = prParams->key_index; prWpiKey->ucKeyID --; if (prWpiKey->ucKeyID > 1) { /* key id is out of range */ //printk(KERN_INFO "[wapi] add key error: key_id invalid %d\n", prWpiKey->ucKeyID); return -EINVAL; } if (prIWEncExt->key_len != 32) { /* key length not valid */ //printk(KERN_INFO "[wapi] add key error: key_len invalid %d\n", prIWEncExt->key_len); return -EINVAL; } //printk(KERN_INFO "[wapi] %d ext_flags %d\n", prEnc->flags, prIWEncExt->ext_flags); if (prIWEncExt->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { prWpiKey->eKeyType = ENUM_WPI_GROUP_KEY; prWpiKey->eDirection = ENUM_WPI_RX; } else if (prIWEncExt->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { prWpiKey->eKeyType = ENUM_WPI_PAIRWISE_KEY; prWpiKey->eDirection = ENUM_WPI_RX_TX; } //#if CFG_SUPPORT_WAPI //handle_sec_msg_final(prIWEncExt->key, 32, prIWEncExt->key, NULL); //#endif /* PN */ memcpy(prWpiKey->aucPN, prIWEncExt->tx_seq, IW_ENCODE_SEQ_MAX_SIZE * 2); /* BSSID */ memcpy(prWpiKey->aucAddrIndex, prIWEncExt->addr, 6); memcpy(prWpiKey->aucWPIEK, prIWEncExt->key, 16); prWpiKey->u4LenWPIEK = 16; memcpy(prWpiKey->aucWPICK, &prIWEncExt->key[16], 16); prWpiKey->u4LenWPICK = 16; rstatus = kalIoctl(prGlueInfo, wlanoidSetWapiKey, prWpiKey, sizeof(PARAM_WPI_KEY_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); if (rstatus != WLAN_STATUS_SUCCESS) { //printk(KERN_INFO "[wapi] add key error:%lx\n", rStatus); fgIsValid = -EFAULT; } } return fgIsValid; }
/*----------------------------------------------------------------------------*/ int mtk_cfg80211_connect ( struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_connect_params *sme ) { P_GLUE_INFO_T prGlueInfo = NULL; WLAN_STATUS rStatus; UINT_32 u4BufLen; ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus; ENUM_PARAM_AUTH_MODE_T eAuthMode; UINT_32 cipher; PARAM_SSID_T rNewSsid; BOOLEAN fgCarryWPSIE = FALSE; ENUM_PARAM_OP_MODE_T eOpMode; prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ASSERT(prGlueInfo); if (prGlueInfo->prAdapter->rWifiVar.rConnSettings.eOPMode > NET_TYPE_AUTO_SWITCH) eOpMode = NET_TYPE_AUTO_SWITCH; else eOpMode = prGlueInfo->prAdapter->rWifiVar.rConnSettings.eOPMode; rStatus = kalIoctl(prGlueInfo, wlanoidSetInfrastructureMode, &eOpMode, sizeof(eOpMode), FALSE, FALSE, TRUE, FALSE, &u4BufLen); if (rStatus != WLAN_STATUS_SUCCESS) { DBGLOG(INIT, INFO, ("wlanoidSetInfrastructureMode fail 0x%lx\n", rStatus)); return -EFAULT; } /* after set operation mode, key table are cleared */ /* reset wpa info */ prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED; prGlueInfo->rWpaInfo.u4KeyMgmt = 0; prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_NONE; prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_NONE; prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM; #if CFG_SUPPORT_802_11W prGlueInfo->rWpaInfo.u4Mfp = IW_AUTH_MFP_DISABLED; #endif if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_WPA; else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_WPA2; else prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED; switch (sme->auth_type) { case NL80211_AUTHTYPE_OPEN_SYSTEM: prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM; break; case NL80211_AUTHTYPE_SHARED_KEY: prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_SHARED_KEY; break; default: prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM | IW_AUTH_ALG_SHARED_KEY; break; } if (sme->crypto.n_ciphers_pairwise) { prGlueInfo->prAdapter->rWifiVar.rConnSettings.rRsnInfo.au4PairwiseKeyCipherSuite[0] = sme->crypto.ciphers_pairwise[0]; switch (sme->crypto.ciphers_pairwise[0]) { case WLAN_CIPHER_SUITE_WEP40: prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_WEP40; break; case WLAN_CIPHER_SUITE_WEP104: prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_WEP104; break; case WLAN_CIPHER_SUITE_TKIP: prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_TKIP; break; case WLAN_CIPHER_SUITE_CCMP: prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_CCMP; break; case WLAN_CIPHER_SUITE_AES_CMAC: prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_CCMP; break; default: DBGLOG(REQ, WARN, ("invalid cipher pairwise (%d)\n", sme->crypto.ciphers_pairwise[0])); return -EINVAL; } } if (sme->crypto.cipher_group) { prGlueInfo->prAdapter->rWifiVar.rConnSettings.rRsnInfo.u4GroupKeyCipherSuite = sme->crypto.cipher_group; switch (sme->crypto.cipher_group) { case WLAN_CIPHER_SUITE_WEP40: prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_WEP40; break; case WLAN_CIPHER_SUITE_WEP104: prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_WEP104; break; case WLAN_CIPHER_SUITE_TKIP: prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_TKIP; break; case WLAN_CIPHER_SUITE_CCMP: prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_CCMP; break; case WLAN_CIPHER_SUITE_AES_CMAC: prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_CCMP; break; default: DBGLOG(REQ, WARN, ("invalid cipher group (%d)\n", sme->crypto.cipher_group)); return -EINVAL; } } if (sme->crypto.n_akm_suites) { prGlueInfo->prAdapter->rWifiVar.rConnSettings.rRsnInfo.au4AuthKeyMgtSuite[0] = sme->crypto.akm_suites[0]; if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA) { switch (sme->crypto.akm_suites[0]) { case WLAN_AKM_SUITE_8021X: eAuthMode = AUTH_MODE_WPA; break; case WLAN_AKM_SUITE_PSK: eAuthMode = AUTH_MODE_WPA_PSK; break; default: DBGLOG(REQ, WARN, ("invalid cipher group (%d)\n", sme->crypto.cipher_group)); return -EINVAL; } } else if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA2) { switch (sme->crypto.akm_suites[0]) { case WLAN_AKM_SUITE_8021X: eAuthMode = AUTH_MODE_WPA2; break; case WLAN_AKM_SUITE_PSK: eAuthMode = AUTH_MODE_WPA2_PSK; break; default: DBGLOG(REQ, WARN, ("invalid cipher group (%d)\n", sme->crypto.cipher_group)); return -EINVAL; } } } if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_DISABLED) { eAuthMode = (prGlueInfo->rWpaInfo.u4AuthAlg == IW_AUTH_ALG_OPEN_SYSTEM) ? AUTH_MODE_OPEN : AUTH_MODE_AUTO_SWITCH; } prGlueInfo->rWpaInfo.fgPrivacyInvoke = sme->privacy; //prGlueInfo->prAdapter->rWifiVar.rConnSettings.fgWapiMode = FALSE; //prGlueInfo->prAdapter->prGlueInfo->u2WapiAssocInfoIESz = 0; prGlueInfo->fgWpsActive = FALSE; //prGlueInfo->prAdapter->prGlueInfo->u2WSCAssocInfoIELen = 0; if (sme->ie && sme->ie_len > 0) { WLAN_STATUS rStatus; UINT_32 u4BufLen; PUINT_8 prDesiredIE = NULL; #if CFG_SUPPORT_WAPI rStatus = kalIoctl(prGlueInfo, wlanoidSetWapiAssocInfo, sme->ie, sme->ie_len, FALSE, FALSE, FALSE, FALSE, &u4BufLen); if (rStatus != WLAN_STATUS_SUCCESS) { DBGLOG(SEC, WARN, ("[wapi] set wapi assoc info error:%lx\n", rStatus)); } #endif #if CFG_SUPPORT_WPS2 if (wextSrchDesiredWPSIE(sme->ie, sme->ie_len, 0xDD, (PUINT_8 *)&prDesiredIE)) { prGlueInfo->fgWpsActive = TRUE; fgCarryWPSIE = TRUE; rStatus = kalIoctl(prGlueInfo, wlanoidSetWSCAssocInfo, prDesiredIE, IE_SIZE(prDesiredIE), FALSE, FALSE, FALSE, FALSE, &u4BufLen); if (rStatus != WLAN_STATUS_SUCCESS) { DBGLOG(SEC, WARN, ("WSC] set WSC assoc info error:%lx\n", rStatus)); } } #endif } /* clear WSC Assoc IE buffer in case WPS IE is not detected */ if(fgCarryWPSIE == FALSE) { kalMemZero(&prGlueInfo->aucWSCAssocInfoIE, 200); prGlueInfo->u2WSCAssocInfoIELen = 0; } rStatus = kalIoctl(prGlueInfo, wlanoidSetAuthMode, &eAuthMode, sizeof(eAuthMode), FALSE, FALSE, FALSE, FALSE, &u4BufLen); if (rStatus != WLAN_STATUS_SUCCESS) { DBGLOG(REQ, WARN, ("set auth mode error:%lx\n", rStatus)); } cipher = prGlueInfo->rWpaInfo.u4CipherGroup | prGlueInfo->rWpaInfo.u4CipherPairwise; if (prGlueInfo->rWpaInfo.fgPrivacyInvoke) { if (cipher & IW_AUTH_CIPHER_CCMP) { eEncStatus = ENUM_ENCRYPTION3_ENABLED; } else if (cipher & IW_AUTH_CIPHER_TKIP) { eEncStatus = ENUM_ENCRYPTION2_ENABLED; } else if (cipher & (IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40)) { eEncStatus = ENUM_ENCRYPTION1_ENABLED; } else if (cipher & IW_AUTH_CIPHER_NONE) { if (prGlueInfo->rWpaInfo.fgPrivacyInvoke) eEncStatus = ENUM_ENCRYPTION1_ENABLED; else eEncStatus = ENUM_ENCRYPTION_DISABLED; } else { eEncStatus = ENUM_ENCRYPTION_DISABLED; } } else { eEncStatus = ENUM_ENCRYPTION_DISABLED; } rStatus = kalIoctl(prGlueInfo, wlanoidSetEncryptionStatus, &eEncStatus, sizeof(eEncStatus), FALSE, FALSE, FALSE, FALSE, &u4BufLen); if (rStatus != WLAN_STATUS_SUCCESS) { DBGLOG(REQ, WARN, ("set encryption mode error:%lx\n", rStatus)); } if (sme->key_len != 0 && prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_DISABLED) { P_PARAM_WEP_T prWepKey = (P_PARAM_WEP_T) wepBuf; kalMemSet(prWepKey, 0, sizeof(prWepKey)); prWepKey->u4Length = 12 + sme->key_len; prWepKey->u4KeyLength = (UINT_32) sme->key_len; prWepKey->u4KeyIndex = (UINT_32) sme->key_idx; prWepKey->u4KeyIndex |= BIT(31); if (prWepKey->u4KeyLength > 32) { DBGLOG(REQ, WARN, ("Too long key length (%u)\n", prWepKey->u4KeyLength)); return -EINVAL; } kalMemCopy(prWepKey->aucKeyMaterial, sme->key, prWepKey->u4KeyLength); rStatus = kalIoctl(prGlueInfo, wlanoidSetAddWep, prWepKey, prWepKey->u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen); if (rStatus != WLAN_STATUS_SUCCESS) { DBGLOG(INIT, INFO, ("wlanoidSetAddWep fail 0x%lx\n", rStatus)); return -EFAULT; } } if(sme->ssid_len > 0) { /* connect by SSID */ COPY_SSID(rNewSsid.aucSsid, rNewSsid.u4SsidLen, sme->ssid, sme->ssid_len); rStatus = kalIoctl(prGlueInfo, wlanoidSetSsid, (PVOID) &rNewSsid, sizeof(PARAM_SSID_T), FALSE, FALSE, TRUE, FALSE, &u4BufLen); if (rStatus != WLAN_STATUS_SUCCESS) { DBGLOG(REQ, WARN, ("set SSID:%lx\n", rStatus)); return -EINVAL; } } else { /* connect by BSSID */ rStatus = kalIoctl(prGlueInfo, wlanoidSetBssid, (PVOID) sme->bssid, sizeof(MAC_ADDR_LEN), FALSE, FALSE, TRUE, FALSE, &u4BufLen); if (rStatus != WLAN_STATUS_SUCCESS) { DBGLOG(REQ, WARN, ("set BSSID:%lx\n", rStatus)); return -EINVAL; } } return 0; }
/*----------------------------------------------------------------------------*/ int mtk_cfg80211_add_key ( struct wiphy *wiphy, struct net_device *ndev, u8 key_index, bool pairwise, const u8 *mac_addr, struct key_params *params ) { PARAM_KEY_T rKey; P_GLUE_INFO_T prGlueInfo = NULL; WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS; INT_32 i4Rslt = -EINVAL; UINT_32 u4BufLen = 0; UINT_8 tmp1[8]; UINT_8 tmp2[8]; prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ASSERT(prGlueInfo); kalMemZero(&rKey, sizeof(PARAM_KEY_T)); rKey.u4KeyIndex = key_index; if(mac_addr) { COPY_MAC_ADDR(rKey.arBSSID, mac_addr); if ((rKey.arBSSID[0] == 0x00) && (rKey.arBSSID[1] == 0x00) && (rKey.arBSSID[2] == 0x00) && (rKey.arBSSID[3] == 0x00) && (rKey.arBSSID[4] == 0x00) && (rKey.arBSSID[5] == 0x00)) { rKey.arBSSID[0] = 0xff; rKey.arBSSID[1] = 0xff; rKey.arBSSID[2] = 0xff; rKey.arBSSID[3] = 0xff; rKey.arBSSID[4] = 0xff; rKey.arBSSID[5] = 0xff; } if (rKey.arBSSID[0] != 0xFF) { rKey.u4KeyIndex |= BIT(31); if ((rKey.arBSSID[0] != 0x00) || (rKey.arBSSID[1] != 0x00) || (rKey.arBSSID[2] != 0x00) || (rKey.arBSSID[3] != 0x00) || (rKey.arBSSID[4] != 0x00) || (rKey.arBSSID[5] != 0x00)) rKey.u4KeyIndex |= BIT(30); } } else { rKey.arBSSID[0] = 0xff; rKey.arBSSID[1] = 0xff; rKey.arBSSID[2] = 0xff; rKey.arBSSID[3] = 0xff; rKey.arBSSID[4] = 0xff; rKey.arBSSID[5] = 0xff; //rKey.u4KeyIndex |= BIT(31); //Enable BIT 31 will make tx use bc key id, should use pairwise key id 0 } if(params->key) { //rKey.aucKeyMaterial[0] = kalMemAlloc(params->key_len, VIR_MEM_TYPE); kalMemCopy(rKey.aucKeyMaterial, params->key, params->key_len); if (params->key_len == 32) { kalMemCopy(tmp1, ¶ms->key[16], 8); kalMemCopy(tmp2, ¶ms->key[24], 8); kalMemCopy(&rKey.aucKeyMaterial[16], tmp2, 8); kalMemCopy(&rKey.aucKeyMaterial[24], tmp1, 8); } } rKey.u4KeyLength = params->key_len; rKey.u4Length = ((UINT_32)&(((P_P2P_PARAM_KEY_T)0)->aucKeyMaterial)) + rKey.u4KeyLength; rStatus = kalIoctl(prGlueInfo, wlanoidSetAddKey, &rKey, rKey.u4Length, FALSE, FALSE, TRUE, FALSE, &u4BufLen); if (rStatus == WLAN_STATUS_SUCCESS) i4Rslt = 0; return i4Rslt; }
/* * This function retrieves the private structure from kernel wiphy structure. */ static void *mwifiex_cfg80211_get_adapter(struct wiphy *wiphy) { return (void *) (*(unsigned long *) wiphy_priv(wiphy)); }
int mtk_cfg80211_get_station ( struct wiphy *wiphy, struct net_device *ndev, u8 *mac, struct station_info *sinfo ) { P_GLUE_INFO_T prGlueInfo = NULL; WLAN_STATUS rStatus; PARAM_MAC_ADDRESS arBssid; UINT_32 u4BufLen, u4Rate; INT_32 i4Rssi; prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy); ASSERT(prGlueInfo); kalMemZero(arBssid, MAC_ADDR_LEN); wlanQueryInformation(prGlueInfo->prAdapter, wlanoidQueryBssid, &arBssid[0], sizeof(arBssid), &u4BufLen); /* 1. check BSSID */ if(UNEQUAL_MAC_ADDR(arBssid, mac)) { /* wrong MAC address */ DBGLOG(REQ, WARN, ("incorrect BSSID: ["MACSTR"] currently connected BSSID["MACSTR"]\n", MAC2STR(mac), MAC2STR(arBssid))); return -ENOENT; } /* 2. fill TX rate */ rStatus = kalIoctl(prGlueInfo, wlanoidQueryLinkSpeed, &u4Rate, sizeof(u4Rate), TRUE, FALSE, FALSE, FALSE, &u4BufLen); if (rStatus != WLAN_STATUS_SUCCESS) { DBGLOG(REQ, WARN, ("unable to retrieve link speed\n")); } else { sinfo->filled |= STATION_INFO_TX_BITRATE; sinfo->txrate.legacy = u4Rate / 1000; /* convert from 100bps to 100kbps */ } if(prGlueInfo->eParamMediaStateIndicated != PARAM_MEDIA_STATE_CONNECTED) { /* not connected */ DBGLOG(REQ, WARN, ("not yet connected\n")); } else { /* 3. fill RSSI */ rStatus = kalIoctl(prGlueInfo, wlanoidQueryRssi, &i4Rssi, sizeof(i4Rssi), TRUE, FALSE, FALSE, FALSE, &u4BufLen); if (rStatus != WLAN_STATUS_SUCCESS) { DBGLOG(REQ, WARN, ("unable to retrieve link speed\n")); } else { sinfo->filled |= STATION_INFO_SIGNAL; //in the cfg80211 layer, the signal is a signed char variable. if(i4Rssi < -128) sinfo->signal = -128; else sinfo->signal = i4Rssi; /* dBm */ } } /* scott.chiang@20130405, refer to 6628's gl_cfg80211.c - made by Zhang.Luo */ sinfo->rx_packets = prGlueInfo->rNetDevStats.rx_packets; sinfo->filled |= STATION_INFO_TX_PACKETS; sinfo->tx_packets = prGlueInfo->rNetDevStats.tx_packets; sinfo->filled |= STATION_INFO_TX_FAILED; #if 1 { WLAN_STATUS rStatus; UINT_32 u4XmitError = 0; // UINT_32 u4XmitOk = 0; // UINT_32 u4RecvError = 0; // UINT_32 u4RecvOk = 0; // UINT_32 u4BufLen; /* @FIX ME: need a more clear way to do this */ rStatus = kalIoctl(prGlueInfo, wlanoidQueryXmitError, &u4XmitError, sizeof(UINT_32), TRUE, TRUE, TRUE, FALSE, &u4BufLen); prGlueInfo->rNetDevStats.tx_errors = u4XmitError; } #else prGlueInfo->rNetDevStats.tx_errors = 0; #endif sinfo->tx_failed = prGlueInfo->rNetDevStats.tx_errors; return 0; }
static int r92su_del_key(struct wiphy *wiphy, struct net_device *ndev, u8 idx, bool pairwise, const u8 *mac_addr) { static const enum r92su_enc_alg no_key = NO_ENCRYPTION; struct r92su *r92su = wiphy_priv(wiphy); struct r92su_key *old_key = NULL; int err = -EAGAIN; mutex_lock(&r92su->lock); if (!r92su_is_connected(r92su)) goto out; if (pairwise) { struct r92su_sta *sta; rcu_read_lock(); sta = r92su_sta_get(r92su, mac_addr); if (sta) { old_key = rcu_dereference(sta->sta_key); /* check if key was uploaded ? */ if (old_key && old_key->uploaded == false) { err = 0; goto out_free; } } rcu_read_unlock(); err = r92su_h2c_set_sta_key(r92su, no_key, mac_addr, NULL); if (err) goto out; rcu_read_lock(); sta = r92su_sta_get(r92su, mac_addr); if (!sta) goto out_free; old_key = rcu_dereference(sta->sta_key); if (old_key) { WARN(!old_key->uploaded, "pairwise-key for station %pM was ninja-deleted", mac_addr); old_key->uploaded = false; } rcu_assign_pointer(sta->sta_key, NULL); } else { struct cfg80211_bss *bss; struct r92su_bss_priv *bss_priv; rcu_read_lock(); bss = rcu_dereference(r92su->connect_bss); if (bss) { bss_priv = r92su_get_bss_priv(bss); old_key = rcu_dereference(bss_priv->group_key[idx]); if (old_key && old_key->uploaded == false) { err = 0; goto out_free; } } rcu_read_unlock(); err = r92su_h2c_set_key(r92su, no_key, idx, !pairwise, NULL); if (err) goto out; rcu_read_lock(); bss = rcu_dereference(r92su->connect_bss); if (bss) { bss_priv = r92su_get_bss_priv(bss); old_key = rcu_dereference(bss_priv->group_key[idx]); if (old_key) old_key->uploaded = false; rcu_assign_pointer(bss_priv->group_key[idx], NULL); } else { /* BSS which held the key is already gone! */ } } out_free: r92su_key_free(old_key); rcu_read_unlock(); out: mutex_unlock(&r92su->lock); return err; }
/* Called after firmware is initialised */ int orinoco_wiphy_register(struct wiphy *wiphy) { struct orinoco_private *priv = wiphy_priv(wiphy); int i, channels = 0; if (priv->firmware_type == FIRMWARE_TYPE_AGERE) wiphy->max_scan_ssids = 1; else wiphy->max_scan_ssids = 0; wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); /* TODO: should we set if we only have demo ad-hoc? * (priv->has_port3) */ if (priv->has_ibss) wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC); if (!priv->broken_monitor || force_monitor) wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR); priv->band.bitrates = orinoco_rates; priv->band.n_bitrates = ARRAY_SIZE(orinoco_rates); /* Only support channels allowed by the card EEPROM */ for (i = 0; i < NUM_CHANNELS; i++) { if (priv->channel_mask & (1 << i)) { priv->channels[i].center_freq = ieee80211_dsss_chan_to_freq(i+1); channels++; } } priv->band.channels = priv->channels; priv->band.n_channels = channels; wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band; wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; i = 0; if (priv->has_wep) { priv->cipher_suites[i] = WLAN_CIPHER_SUITE_WEP40; i++; if (priv->has_big_wep) { priv->cipher_suites[i] = WLAN_CIPHER_SUITE_WEP104; i++; } } if (priv->has_wpa) { priv->cipher_suites[i] = WLAN_CIPHER_SUITE_TKIP; i++; } wiphy->cipher_suites = priv->cipher_suites; wiphy->n_cipher_suites = i; wiphy->rts_threshold = priv->rts_thresh; if (!priv->has_mwo) wiphy->frag_threshold = priv->frag_thresh; return wiphy_register(wiphy); }
int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter) { int ret; void *wdev_priv; struct wiphy *wiphy; struct mwifiex_private *priv = adapter->priv[MWIFIEX_BSS_TYPE_STA]; u8 *country_code; /* create a new wiphy for use with cfg80211 */ wiphy = wiphy_new(&mwifiex_cfg80211_ops, sizeof(struct mwifiex_adapter *)); if (!wiphy) { dev_err(adapter->dev, "%s: creating new wiphy\n", __func__); return -ENOMEM; } wiphy->max_scan_ssids = MWIFIEX_MAX_SSID_LIST_LENGTH; wiphy->max_scan_ie_len = MWIFIEX_MAX_VSIE_LEN; wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP); wiphy->bands[IEEE80211_BAND_2GHZ] = &mwifiex_band_2ghz; if (adapter->config_bands & BAND_A) wiphy->bands[IEEE80211_BAND_5GHZ] = &mwifiex_band_5ghz; else wiphy->bands[IEEE80211_BAND_5GHZ] = NULL; wiphy->iface_combinations = &mwifiex_iface_comb_ap_sta; wiphy->n_iface_combinations = 1; /* Initialize cipher suits */ wiphy->cipher_suites = mwifiex_cipher_suites; wiphy->n_cipher_suites = ARRAY_SIZE(mwifiex_cipher_suites); memcpy(wiphy->perm_addr, priv->curr_addr, ETH_ALEN); wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME | WIPHY_FLAG_CUSTOM_REGULATORY; /* Reserve space for mwifiex specific private data for BSS */ wiphy->bss_priv_size = sizeof(struct mwifiex_bss_priv); wiphy->reg_notifier = mwifiex_reg_notifier; /* Set struct mwifiex_adapter pointer in wiphy_priv */ wdev_priv = wiphy_priv(wiphy); *(unsigned long *)wdev_priv = (unsigned long)adapter; set_wiphy_dev(wiphy, (struct device *)priv->adapter->dev); ret = wiphy_register(wiphy); if (ret < 0) { dev_err(adapter->dev, "%s: wiphy_register failed: %d\n", __func__, ret); wiphy_free(wiphy); return ret; } country_code = mwifiex_11d_code_2_region(priv->adapter->region_code); if (country_code && regulatory_hint(wiphy, country_code)) dev_err(adapter->dev, "regulatory_hint() failed\n"); adapter->wiphy = wiphy; return ret; }