int sip_send_setkey(struct esp_pub *epub, u8 bssid_no, u8 *peer_addr, struct ieee80211_key_conf *key, u8 isvalid) { struct sip_cmd_setkey *setkeycmd; struct sk_buff *skb = NULL; skb = sip_alloc_ctrl_skbuf(epub->sip, sizeof(struct sip_cmd_setkey) + sizeof(struct sip_hdr), SIP_CMD_SETKEY); if (!skb) return -EINVAL; setkeycmd = (struct sip_cmd_setkey *)(skb->data + sizeof(struct sip_hdr)); if (peer_addr) { memcpy(setkeycmd->addr, peer_addr, ETH_ALEN); } else { memset(setkeycmd->addr, 0, ETH_ALEN); } setkeycmd->bssid_no = bssid_no; setkeycmd->hw_key_idx= key->hw_key_idx; if (isvalid) { #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39)) setkeycmd->alg= key->alg; #else setkeycmd->alg= esp_cipher2alg(key->cipher); #endif /* NEW_KERNEL */ setkeycmd->keyidx = key->keyidx; setkeycmd->keylen = key->keylen; #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39)) if (key->alg == ALG_TKIP) { #else if (key->cipher == WLAN_CIPHER_SUITE_TKIP) { #endif /* NEW_KERNEL */ memcpy(setkeycmd->key, key->key, 16); memcpy(setkeycmd->key+16,key->key+24,8); memcpy(setkeycmd->key+24,key->key+16,8); } else { memcpy(setkeycmd->key, key->key, key->keylen); } setkeycmd->flags=1; } else { setkeycmd->flags=0; } return sip_cmd_enqueue(epub->sip, skb); } #ifdef FPGA_LOOPBACK #define LOOPBACK_PKT_LEN 200 int sip_send_loopback_cmd_mblk(struct esp_sip *sip) { int cnt, ret; for (cnt = 0; cnt < 4; cnt++) { if (0!=(ret=sip_send_loopback_mblk(sip, LOOPBACK_PKT_LEN, LOOPBACK_PKT_LEN, 0))) return ret; } return 0; }
int sip_send_ps_config(struct esp_pub *epub, struct esp_ps *ps) { struct sip_cmd_ps *pscmd = NULL; struct sk_buff *skb = NULL; struct sip_hdr *shdr = NULL; skb = sip_alloc_ctrl_skbuf(epub->sip, sizeof(struct sip_cmd_ps) + sizeof(struct sip_hdr), SIP_CMD_PS); if (!skb) return -1; shdr = (struct sip_hdr *)skb->data; pscmd = (struct sip_cmd_ps *)(skb->data + sizeof(struct sip_hdr)); pscmd->dtim_period = ps->dtim_period; pscmd->max_sleep_period = ps->max_sleep_period; #if 0 if (atomic_read(&ps->state) == ESP_PM_TURNING_ON) { pscmd->on = 1; SIP_HDR_SET_PM_TURNING_ON(shdr); } else if (atomic_read(&ps->state) == ESP_PM_TURNING_OFF) { pscmd->on = 0; SIP_HDR_SET_PM_TURNING_OFF(shdr); } else { esp_dbg(ESP_DBG_ERROR, "%s PM WRONG STATE %d\n", __func__, atomic_read(&ps->state)); ASSERT(0); } #endif return sip_cmd_enqueue(epub->sip, skb); }
int sip_send_ampdu_action(struct esp_pub *epub, u8 action_num, const u8 * addr, u16 tid, u16 ssn, u8 buf_size) { u8 index = find_empty_index(epub); struct sk_buff *skb = NULL; struct sip_cmd_ampdu_action * action; if(index < 0) return -1; skb = sip_alloc_ctrl_skbuf(epub->sip, sizeof(struct sip_cmd_ampdu_action) + sizeof(struct sip_hdr), SIP_CMD_AMPDU_ACTION); if(!skb) return -1; action = (struct sip_cmd_ampdu_action *)(skb->data + sizeof(struct sip_hdr)); action->action = action_num; //for TX, it means interface index action->index = ssn; switch(action_num) { case SIP_AMPDU_RX_START: action->ssn = ssn; case SIP_AMPDU_RX_STOP: action->index = tid; case SIP_AMPDU_TX_OPERATIONAL: case SIP_AMPDU_TX_STOP: action->win_size = buf_size; action->tid = tid; memcpy(action->addr, addr, ETH_ALEN); break; } return sip_cmd_enqueue(epub->sip, skb); }
/*send cmd to target, if aborted is true, inform target stop scan, report scan complete imediately return 1: complete over, 0: success, still have next scan, -1: hardware failure */ int sip_send_scan(struct esp_pub *epub) { struct cfg80211_scan_request *scan_req = epub->wl.scan_req; struct sk_buff *skb = NULL; struct sip_cmd_scan *scancmd; u8 *ptr = NULL; int i; u8 append_len, ssid_len; ESSERT(scan_req != NULL); ssid_len = scan_req->n_ssids == 0 ? 0: (scan_req->n_ssids == 1 ? scan_req->ssids->ssid_len: scan_req->ssids->ssid_len + (scan_req->ssids + 1)->ssid_len); append_len = ssid_len + scan_req->n_channels + scan_req->ie_len; skb = sip_alloc_ctrl_skbuf(epub->sip, sizeof(struct sip_cmd_scan) + sizeof(struct sip_hdr) + append_len, SIP_CMD_SCAN); if (!skb) return -EINVAL; ptr = skb->data; scancmd = (struct sip_cmd_scan *)(ptr + sizeof(struct sip_hdr)); ptr += sizeof(struct sip_hdr); scancmd->aborted= false; if (scancmd->aborted==false) { ptr += sizeof(struct sip_cmd_scan); if (scan_req->n_ssids <=0 || (scan_req->n_ssids == 1&& ssid_len == 0)) { scancmd->ssid_len = 0; } else { scancmd->ssid_len = ssid_len; if(scan_req->ssids->ssid_len == ssid_len) memcpy(ptr, scan_req->ssids->ssid, scancmd->ssid_len); else memcpy(ptr, (scan_req->ssids + 1)->ssid, scancmd->ssid_len); } ptr += scancmd->ssid_len; scancmd->n_channels=scan_req->n_channels; for (i=0; i<scan_req->n_channels; i++) ptr[i] = scan_req->channels[i]->hw_value; ptr += scancmd->n_channels; if (scan_req->ie_len && scan_req->ie != NULL) { scancmd->ie_len=scan_req->ie_len; memcpy(ptr, scan_req->ie, scan_req->ie_len); } else { scancmd->ie_len = 0; } //add a flag that support two ssids, if(scan_req->n_ssids > 1) scancmd->ssid_len |= 0x80; } return sip_cmd_enqueue(epub->sip, skb); }
int sip_cmd(struct esp_pub *epub, enum sip_cmd_id cmd_id, u8 *cmd_buf, u8 cmd_len) { struct sk_buff *skb = NULL; skb = sip_alloc_ctrl_skbuf(epub->sip, cmd_len + sizeof(struct sip_hdr), cmd_id); if (!skb) return -ENOMEM; memcpy(skb->data + sizeof(struct sip_hdr), cmd_buf, cmd_len); return sip_cmd_enqueue(epub->sip, skb); }
//remain_on_channel int sip_send_roc(struct esp_pub *epub, u16 center_freq, u16 duration) { struct sk_buff *skb = NULL; struct sip_cmd_config *configcmd; skb = sip_alloc_ctrl_skbuf(epub->sip, sizeof(struct sip_cmd_config) + sizeof(struct sip_hdr), SIP_CMD_CONFIG); if (!skb) return -EINVAL; configcmd = (struct sip_cmd_config *)(skb->data + sizeof(struct sip_hdr)); configcmd->center_freq= center_freq; configcmd->duration= duration; return sip_cmd_enqueue(epub->sip, skb); }
int sip_send_suspend_config(struct esp_pub *epub, u8 suspend) { struct sip_cmd_suspend *cmd = NULL; struct sk_buff *skb = NULL; skb = sip_alloc_ctrl_skbuf(epub->sip, sizeof(struct sip_cmd_suspend) + sizeof(struct sip_hdr), SIP_CMD_SUSPEND); if (!skb) return -EINVAL; cmd = (struct sip_cmd_suspend *)(skb->data + sizeof(struct sip_hdr)); cmd->suspend = suspend; return sip_cmd_enqueue(epub->sip, skb); }
int sip_send_config(struct esp_pub *epub, struct ieee80211_conf * conf) { struct sk_buff *skb = NULL; struct sip_cmd_config *configcmd; skb = sip_alloc_ctrl_skbuf(epub->sip, sizeof(struct sip_cmd_config) + sizeof(struct sip_hdr), SIP_CMD_CONFIG); if (!skb) return -1; esp_dbg(ESP_DBG_TRACE, "%s config center freq %d\n", __func__, conf->channel->center_freq); configcmd = (struct sip_cmd_config *)(skb->data + sizeof(struct sip_hdr)); configcmd->center_freq= conf->channel->center_freq; configcmd->duration= 0; return sip_cmd_enqueue(epub->sip, skb); }
int sip_send_loopback_mblk(struct esp_sip *sip, int txpacket_len, int rxpacket_len, int packet_id) { struct sk_buff *skb = NULL; struct sip_cmd_loopback *cmd; u8 *ptr = NULL; int i, ret; //send 100 loopback pkt if(txpacket_len) skb = sip_alloc_ctrl_skbuf(sip, sizeof(struct sip_cmd_loopback) + sizeof(struct sip_hdr) + txpacket_len, SIP_CMD_LOOPBACK); else skb = sip_alloc_ctrl_skbuf(sip, sizeof(struct sip_cmd_loopback) + sizeof(struct sip_hdr), SIP_CMD_LOOPBACK); if (!skb) return -ENOMEM; ptr = skb->data; cmd = (struct sip_cmd_loopback *)(ptr + sizeof(struct sip_hdr)); ptr += sizeof(struct sip_hdr); cmd->txlen = txpacket_len; cmd->rxlen = rxpacket_len; cmd->pack_id = packet_id; if (txpacket_len) { ptr += sizeof(struct sip_cmd_loopback); /* fill up pkt payload */ for (i = 0; i < txpacket_len; i++) { ptr[i] = i; } } ret = sip_cmd_enqueue(sip, skb); if (ret <0) return ret; return 0; }
int sip_send_wmm_params(struct esp_pub *epub, u8 aci, const struct ieee80211_tx_queue_params *params) { struct sk_buff *skb = NULL; struct sip_cmd_set_wmm_params* bsscmd; skb = sip_alloc_ctrl_skbuf(epub->sip, sizeof(struct sip_cmd_set_wmm_params) + sizeof(struct sip_hdr), SIP_CMD_SET_WMM_PARAM); if (!skb) return -EINVAL; bsscmd = (struct sip_cmd_set_wmm_params *)(skb->data + sizeof(struct sip_hdr)); bsscmd->aci= aci; bsscmd->aifs=params->aifs; bsscmd->txop_us=params->txop*32; bsscmd->ecw_min = 32 - __builtin_clz(params->cw_min); bsscmd->ecw_max= 32 -__builtin_clz(params->cw_max); return sip_cmd_enqueue(epub->sip, skb); }
int sip_send_ps_config(struct esp_pub *epub, struct esp_ps *ps) { struct sip_cmd_ps *pscmd = NULL; struct sk_buff *skb = NULL; struct sip_hdr *shdr = NULL; skb = sip_alloc_ctrl_skbuf(epub->sip, sizeof(struct sip_cmd_ps) + sizeof(struct sip_hdr), SIP_CMD_PS); if (!skb) return -EINVAL; shdr = (struct sip_hdr *)skb->data; pscmd = (struct sip_cmd_ps *)(skb->data + sizeof(struct sip_hdr)); pscmd->dtim_period = ps->dtim_period; pscmd->max_sleep_period = ps->max_sleep_period; return sip_cmd_enqueue(epub->sip, skb); }
int sip_send_config(struct esp_pub *epub, struct ieee80211_conf * conf) { struct sk_buff *skb = NULL; struct sip_cmd_config *configcmd; skb = sip_alloc_ctrl_skbuf(epub->sip, sizeof(struct sip_cmd_config) + sizeof(struct sip_hdr), SIP_CMD_CONFIG); if (!skb) return -EINVAL; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)) esp_dbg(ESP_DBG_TRACE, "%s config center freq %d\n", __func__, conf->chandef.chan->center_freq); #else esp_dbg(ESP_DBG_TRACE, "%s config center freq %d\n", __func__, conf->channel->center_freq); #endif configcmd = (struct sip_cmd_config *)(skb->data + sizeof(struct sip_hdr)); #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)) configcmd->center_freq= conf->chandef.chan->center_freq; #else configcmd->center_freq= conf->channel->center_freq; #endif configcmd->duration= 0; return sip_cmd_enqueue(epub->sip, skb); }
int sip_send_bss_info_update(struct esp_pub *epub, struct esp_vif *evif, u8 *bssid, int assoc) { struct sk_buff *skb = NULL; struct sip_cmd_bss_info_update*bsscmd; skb = sip_alloc_ctrl_skbuf(epub->sip, sizeof(struct sip_cmd_bss_info_update) + sizeof(struct sip_hdr), SIP_CMD_BSS_INFO_UPDATE); if (!skb) return -1; bsscmd = (struct sip_cmd_bss_info_update *)(skb->data + sizeof(struct sip_hdr)); if (assoc == 2) { //hack for softAP mode bsscmd->beacon_int = evif->beacon_interval; } else if (assoc == 1) { set_bit(ESP_WL_FLAG_CONNECT, &epub->wl.flags); } else { clear_bit(ESP_WL_FLAG_CONNECT, &epub->wl.flags); } bsscmd->bssid_no = evif->index; bsscmd->isassoc= assoc; memcpy(bsscmd->bssid, bssid, ETH_ALEN); return sip_cmd_enqueue(epub->sip, skb); }
int sip_send_set_sta(struct esp_pub *epub, u8 ifidx, u8 set, struct esp_node *node, struct ieee80211_vif *vif, u8 index) #endif { struct sk_buff *skb = NULL; struct sip_cmd_setsta *setstacmd; #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28)) struct ieee80211_ht_info ht_info = node->ht_info; #endif skb = sip_alloc_ctrl_skbuf(epub->sip, sizeof(struct sip_cmd_setsta) + sizeof(struct sip_hdr), SIP_CMD_SETSTA); if (!skb) return -EINVAL; setstacmd = (struct sip_cmd_setsta *)(skb->data + sizeof(struct sip_hdr)); setstacmd->ifidx = ifidx; setstacmd->index = index; setstacmd->set = set; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)) if(sta->aid == 0) setstacmd->aid = vif->bss_conf.aid; else setstacmd->aid = sta->aid; memcpy(setstacmd->mac, sta->addr, ETH_ALEN); if(set){ if(sta->ht_cap.ht_supported){ if(sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) setstacmd->phymode = ESP_IEEE80211_T_HT20_S; else setstacmd->phymode = ESP_IEEE80211_T_HT20_L; setstacmd->ampdu_factor = sta->ht_cap.ampdu_factor; setstacmd->ampdu_density = sta->ht_cap.ampdu_density; } else { if(sta->supp_rates[IEEE80211_BAND_2GHZ] & (~(u32)CONF_HW_BIT_RATE_11B_MASK)){ setstacmd->phymode = ESP_IEEE80211_T_OFDM; } else { setstacmd->phymode = ESP_IEEE80211_T_CCK; } } } #else setstacmd->aid = node->aid; memcpy(setstacmd->mac, node->addr, ETH_ALEN); if(set){ if(ht_info.ht_supported){ if(ht_info.cap & IEEE80211_HT_CAP_SGI_20) setstacmd->phymode = ESP_IEEE80211_T_HT20_S; else setstacmd->phymode = ESP_IEEE80211_T_HT20_L; setstacmd->ampdu_factor = ht_info.ampdu_factor; setstacmd->ampdu_density = ht_info.ampdu_density; } else { //note supp_rates is u64[] in 2.6.27 if(node->supp_rates[IEEE80211_BAND_2GHZ] & (~(u64)CONF_HW_BIT_RATE_11B_MASK)){ setstacmd->phymode = ESP_IEEE80211_T_OFDM; } else { setstacmd->phymode = ESP_IEEE80211_T_CCK; } } } #endif return sip_cmd_enqueue(epub->sip, skb); }