/* * Fill in probe request with the following parameters: * TA is our vif HW address, which mac80211 ensures we have. * Packet is broadcasted, so this is both SA and DA. * The probe request IE is made out of two: first comes the most prioritized * SSID if a directed scan is requested. Second comes whatever extra * information was given to us as the scan request IE. */ static u16 iwl_mvm_fill_probe_req(struct ieee80211_mgmt *frame, const u8 *ta, int n_ssids, const u8 *ssid, int ssid_len, const u8 *ie, int ie_len, int left) { int len = 0; u8 *pos = NULL; /* Make sure there is enough space for the probe request, * two mandatory IEs and the data */ left -= 24; if (left < 0) return 0; frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ); eth_broadcast_addr(frame->da); memcpy(frame->sa, ta, ETH_ALEN); eth_broadcast_addr(frame->bssid); frame->seq_ctrl = 0; len += 24; /* for passive scans, no need to fill anything */ if (n_ssids == 0) return (u16)len; /* points to the payload of the request */ pos = &frame->u.probe_req.variable[0]; /* fill in our SSID IE */ left -= ssid_len + 2; if (left < 0) return 0; *pos++ = WLAN_EID_SSID; *pos++ = ssid_len; if (ssid && ssid_len) { /* ssid_len may be == 0 even if ssid is valid */ memcpy(pos, ssid, ssid_len); pos += ssid_len; } len += ssid_len + 2; if (WARN_ON(left < ie_len)) return len; if (ie && ie_len) { memcpy(pos, ie, ie_len); len += ie_len; } return (u16)len; }
static void iwl_mvm_build_unified_scan_probe(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct ieee80211_scan_ies *ies, struct iwl_scan_probe_req *preq, const u8 *mac_addr, const u8 *mac_addr_mask) { struct ieee80211_mgmt *frame = (struct ieee80211_mgmt *)preq->buf; u8 *pos, *newpos; /* * Unfortunately, right now the offload scan doesn't support randomising * within the firmware, so until the firmware API is ready we implement * it in the driver. This means that the scan iterations won't really be * random, only when it's restarted, but at least that helps a bit. */ if (mac_addr) get_random_mask_addr(frame->sa, mac_addr, mac_addr_mask); else memcpy(frame->sa, vif->addr, ETH_ALEN); frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ); eth_broadcast_addr(frame->da); eth_broadcast_addr(frame->bssid); frame->seq_ctrl = 0; pos = frame->u.probe_req.variable; *pos++ = WLAN_EID_SSID; *pos++ = 0; preq->mac_header.offset = 0; preq->mac_header.len = cpu_to_le16(24 + 2); /* Insert ds parameter set element on 2.4 GHz band */ newpos = iwl_mvm_copy_and_insert_ds_elem(mvm, ies->ies[IEEE80211_BAND_2GHZ], ies->len[IEEE80211_BAND_2GHZ], pos); preq->band_data[0].offset = cpu_to_le16(pos - preq->buf); preq->band_data[0].len = cpu_to_le16(newpos - pos); pos = newpos; memcpy(pos, ies->ies[IEEE80211_BAND_5GHZ], ies->len[IEEE80211_BAND_5GHZ]); preq->band_data[1].offset = cpu_to_le16(pos - preq->buf); preq->band_data[1].len = cpu_to_le16(ies->len[IEEE80211_BAND_5GHZ]); pos += ies->len[IEEE80211_BAND_5GHZ]; memcpy(pos, ies->common_ies, ies->common_ie_len); preq->common_data.offset = cpu_to_le16(pos - preq->buf); preq->common_data.len = cpu_to_le16(ies->common_ie_len); }
/** * lbs_setup_firmware - gets the HW spec from the firmware and sets * some basic parameters * * @priv: A pointer to &struct lbs_private structure * returns: 0 or -1 */ static int lbs_setup_firmware(struct lbs_private *priv) { int ret = -1; s16 curlevel = 0, minlevel = 0, maxlevel = 0; lbs_deb_enter(LBS_DEB_FW); /* Read MAC address from firmware */ eth_broadcast_addr(priv->current_addr); ret = lbs_update_hw_spec(priv); if (ret) goto done; /* Read power levels if available */ ret = lbs_get_tx_power(priv, &curlevel, &minlevel, &maxlevel); if (ret == 0) { priv->txpower_cur = curlevel; priv->txpower_min = minlevel; priv->txpower_max = maxlevel; } /* Send cmd to FW to enable 11D function */ ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_11D_ENABLE, 1); if (ret) goto done; ret = lbs_set_mac_control_sync(priv); done: lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret); return ret; }
static void ath9k_htc_set_mac_bssid_mask(struct ath9k_htc_priv *priv, struct ieee80211_vif *vif) { struct ath_common *common = ath9k_hw_common(priv->ah); struct ath9k_vif_iter_data iter_data; /* * Pick the MAC address of the first interface as the new hardware * MAC address. The hardware will use it together with the BSSID mask * when matching addresses. */ iter_data.hw_macaddr = NULL; eth_broadcast_addr(iter_data.mask); if (vif) ath9k_htc_bssid_iter(&iter_data, vif->addr, vif); /* Get list of all active MAC addresses */ ieee80211_iterate_active_interfaces_atomic( priv->hw, IEEE80211_IFACE_ITER_RESUME_ALL, ath9k_htc_bssid_iter, &iter_data); memcpy(common->bssidmask, iter_data.mask, ETH_ALEN); if (iter_data.hw_macaddr) memcpy(common->macaddr, iter_data.hw_macaddr, ETH_ALEN); ath_hw_setbssidmask(common); }
static void ath9k_init_misc(struct ath_softc *sc) { struct ath_common *common = ath9k_hw_common(sc->sc_ah); int i = 0; timer_setup(&common->ani.timer, ath_ani_calibrate, 0); common->last_rssi = ATH_RSSI_DUMMY_MARKER; eth_broadcast_addr(common->bssidmask); sc->beacon.slottime = 9; for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) sc->beacon.bslot[i] = NULL; if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) sc->ant_comb.count = ATH_ANT_DIV_COMB_INIT_COUNT; sc->spec_priv.ah = sc->sc_ah; sc->spec_priv.spec_config.enabled = 0; sc->spec_priv.spec_config.short_repeat = true; sc->spec_priv.spec_config.count = 8; sc->spec_priv.spec_config.endless = false; sc->spec_priv.spec_config.period = 0xFF; sc->spec_priv.spec_config.fft_period = 0xF; }
static int p54_start(struct ieee80211_hw *dev) { struct p54_common *priv = dev->priv; int err; mutex_lock(&priv->conf_mutex); err = priv->open(dev); if (err) goto out; P54_SET_QUEUE(priv->qos_params[0], 0x0002, 0x0003, 0x0007, 47); P54_SET_QUEUE(priv->qos_params[1], 0x0002, 0x0007, 0x000f, 94); P54_SET_QUEUE(priv->qos_params[2], 0x0003, 0x000f, 0x03ff, 0); P54_SET_QUEUE(priv->qos_params[3], 0x0007, 0x000f, 0x03ff, 0); err = p54_set_edcf(priv); if (err) goto out; eth_broadcast_addr(priv->bssid); priv->mode = NL80211_IFTYPE_MONITOR; err = p54_setup_mac(priv); if (err) { priv->mode = NL80211_IFTYPE_UNSPECIFIED; goto out; } ieee80211_queue_delayed_work(dev, &priv->work, 0); priv->softled_state = 0; err = p54_set_leds(priv); out: mutex_unlock(&priv->conf_mutex); return err; }
static int lbs_init_adapter(struct lbs_private *priv) { int ret; lbs_deb_enter(LBS_DEB_MAIN); eth_broadcast_addr(priv->current_addr); priv->connect_status = LBS_DISCONNECTED; priv->channel = DEFAULT_AD_HOC_CHANNEL; priv->mac_control = CMD_ACT_MAC_RX_ON | CMD_ACT_MAC_TX_ON; priv->radio_on = 1; priv->psmode = LBS802_11POWERMODECAM; priv->psstate = PS_STATE_FULL_POWER; priv->is_deep_sleep = 0; priv->is_auto_deep_sleep_enabled = 0; priv->deep_sleep_required = 0; priv->wakeup_dev_required = 0; init_waitqueue_head(&priv->ds_awake_q); init_waitqueue_head(&priv->scan_q); priv->authtype_auto = 1; priv->is_host_sleep_configured = 0; priv->is_host_sleep_activated = 0; init_waitqueue_head(&priv->host_sleep_q); init_waitqueue_head(&priv->fw_waitq); mutex_init(&priv->lock); setup_timer(&priv->command_timer, lbs_cmd_timeout_handler, (unsigned long)priv); setup_timer(&priv->tx_lockup_timer, lbs_tx_lockup_handler, (unsigned long)priv); setup_timer(&priv->auto_deepsleep_timer, auto_deepsleep_timer_fn, (unsigned long)priv); INIT_LIST_HEAD(&priv->cmdfreeq); INIT_LIST_HEAD(&priv->cmdpendingq); spin_lock_init(&priv->driver_lock); /* Allocate the command buffers */ if (lbs_allocate_cmd_buffer(priv)) { pr_err("Out of memory allocating command buffers\n"); ret = -ENOMEM; goto out; } priv->resp_idx = 0; priv->resp_len[0] = priv->resp_len[1] = 0; /* Create the event FIFO */ ret = kfifo_alloc(&priv->event_fifo, sizeof(u32) * 16, GFP_KERNEL); if (ret) { pr_err("Out of memory allocating event FIFO buffer\n"); goto out; } out: lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret); return ret; }
static int l2tp_eth_dev_init(struct net_device *dev) { struct l2tp_eth *priv = netdev_priv(dev); priv->dev = dev; eth_hw_addr_random(dev); eth_broadcast_addr(dev->broadcast); dev->qdisc_tx_busylock = &l2tp_eth_tx_busylock; return 0; }
static int l2tp_eth_dev_init(struct net_device *dev) { struct l2tp_eth *priv = netdev_priv(dev); priv->dev = dev; eth_hw_addr_random(dev); eth_broadcast_addr(dev->broadcast); netdev_lockdep_set_classes(dev); return 0; }
void bnep_net_setup(struct net_device *dev) { eth_broadcast_addr(dev->broadcast); dev->addr_len = ETH_ALEN; ether_setup(dev); dev->priv_flags &= ~IFF_TX_SKB_SHARING; dev->netdev_ops = &bnep_netdev_ops; dev->watchdog_timeo = HZ * 2; }
/** * ether_setup - setup Ethernet network device * @dev: network device * * Fill in the fields of the device structure with Ethernet-generic values. */ void ether_setup(struct net_device *dev) { dev->header_ops = ð_header_ops; dev->type = ARPHRD_ETHER; dev->hard_header_len = ETH_HLEN; dev->mtu = ETH_DATA_LEN; dev->addr_len = ETH_ALEN; dev->tx_queue_len = 1000; /* Ethernet wants good queues */ dev->flags = IFF_BROADCAST|IFF_MULTICAST; dev->priv_flags |= IFF_TX_SKB_SHARING; eth_broadcast_addr(dev->broadcast); }
/** * ether_setup - setup Ethernet network device * @dev: network device * * Fill in the fields of the device structure with Ethernet-generic values. */ void ether_setup(struct net_device *dev) { dev->header_ops = ð_header_ops; dev->type = ARPHRD_ETHER; dev->hard_header_len = ETH_HLEN; dev->mtu = ETH_DATA_LEN; dev->min_mtu = ETH_MIN_MTU; dev->max_mtu = ETH_DATA_LEN; dev->addr_len = ETH_ALEN; dev->tx_queue_len = DEFAULT_TX_QUEUE_LEN; dev->flags = IFF_BROADCAST|IFF_MULTICAST; dev->priv_flags |= IFF_TX_SKB_SHARING; eth_broadcast_addr(dev->broadcast); }
static int mt7603_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct mt7603_vif *mvif = (struct mt7603_vif *) vif->drv_priv; struct mt7603_dev *dev = hw->priv; u8 bc_addr[ETH_ALEN]; int idx; int ret = 0; mutex_lock(&dev->mutex); mvif->idx = ffs(~dev->vif_mask) - 1; if (mvif->idx >= MT7603_MAX_INTERFACES) { ret = -ENOSPC; goto out; } mt76_wr(dev, MT_MAC_ADDR0(mvif->idx), get_unaligned_le32(vif->addr)); mt76_wr(dev, MT_MAC_ADDR1(mvif->idx), (get_unaligned_le16(vif->addr + 4) | MT_MAC_ADDR1_VALID)); idx = MT7603_WTBL_RESERVED - 1 - mvif->idx; dev->vif_mask |= BIT(mvif->idx); mvif->sta.wcid.idx = idx; mvif->sta.wcid.hw_key_idx = -1; eth_broadcast_addr(bc_addr); mt7603_wtbl_init(dev, idx, bc_addr); rcu_assign_pointer(dev->wcid[idx], &mvif->sta.wcid); mt7603_txq_init(dev, vif->txq); out: mutex_unlock(&dev->mutex); return ret; }
/* * This function initializes the private structure and sets default * values to the members. * * Additionally, it also initializes all the locks and sets up all the * lists. */ int mwifiex_init_priv(struct mwifiex_private *priv) { u32 i; priv->media_connected = false; eth_broadcast_addr(priv->curr_addr); priv->port_open = false; priv->usb_port = MWIFIEX_USB_EP_DATA; priv->pkt_tx_ctrl = 0; priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; priv->data_rate = 0; /* Initially indicate the rate as auto */ priv->is_data_rate_auto = true; priv->bcn_avg_factor = DEFAULT_BCN_AVG_FACTOR; priv->data_avg_factor = DEFAULT_DATA_AVG_FACTOR; priv->sec_info.wep_enabled = 0; priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM; priv->sec_info.encryption_mode = 0; for (i = 0; i < ARRAY_SIZE(priv->wep_key); i++) memset(&priv->wep_key[i], 0, sizeof(struct mwifiex_wep_key)); priv->wep_key_curr_index = 0; priv->curr_pkt_filter = HostCmd_ACT_MAC_RX_ON | HostCmd_ACT_MAC_TX_ON | HostCmd_ACT_MAC_ETHERNETII_ENABLE; priv->beacon_period = 100; /* beacon interval */ priv->attempted_bss_desc = NULL; memset(&priv->curr_bss_params, 0, sizeof(priv->curr_bss_params)); priv->listen_interval = MWIFIEX_DEFAULT_LISTEN_INTERVAL; memset(&priv->prev_ssid, 0, sizeof(priv->prev_ssid)); memset(&priv->prev_bssid, 0, sizeof(priv->prev_bssid)); memset(&priv->assoc_rsp_buf, 0, sizeof(priv->assoc_rsp_buf)); priv->assoc_rsp_size = 0; priv->adhoc_channel = DEFAULT_AD_HOC_CHANNEL; priv->atim_window = 0; priv->adhoc_state = ADHOC_IDLE; priv->tx_power_level = 0; priv->max_tx_power_level = 0; priv->min_tx_power_level = 0; priv->tx_rate = 0; priv->rxpd_htinfo = 0; priv->rxpd_rate = 0; priv->rate_bitmap = 0; priv->data_rssi_last = 0; priv->data_rssi_avg = 0; priv->data_nf_avg = 0; priv->data_nf_last = 0; priv->bcn_rssi_last = 0; priv->bcn_rssi_avg = 0; priv->bcn_nf_avg = 0; priv->bcn_nf_last = 0; memset(&priv->wpa_ie, 0, sizeof(priv->wpa_ie)); memset(&priv->aes_key, 0, sizeof(priv->aes_key)); priv->wpa_ie_len = 0; priv->wpa_is_gtk_set = false; memset(&priv->assoc_tlv_buf, 0, sizeof(priv->assoc_tlv_buf)); priv->assoc_tlv_buf_len = 0; memset(&priv->wps, 0, sizeof(priv->wps)); memset(&priv->gen_ie_buf, 0, sizeof(priv->gen_ie_buf)); priv->gen_ie_buf_len = 0; memset(priv->vs_ie, 0, sizeof(priv->vs_ie)); priv->wmm_required = true; priv->wmm_enabled = false; priv->wmm_qosinfo = 0; priv->curr_bcn_buf = NULL; priv->curr_bcn_size = 0; priv->wps_ie = NULL; priv->wps_ie_len = 0; priv->ap_11n_enabled = 0; memset(&priv->roc_cfg, 0, sizeof(priv->roc_cfg)); priv->scan_block = false; priv->csa_chan = 0; priv->csa_expire_time = 0; priv->del_list_idx = 0; priv->hs2_enabled = false; priv->check_tdls_tx = false; memcpy(priv->tos_to_tid_inv, tos_to_tid_inv, MAX_NUM_TID); mwifiex_init_11h_params(priv); return mwifiex_add_bss_prio_tbl(priv); }
int ncsi_xmit_cmd(struct ncsi_cmd_arg *nca) { struct ncsi_request *nr; struct ethhdr *eh; struct ncsi_cmd_handler *nch = NULL; int i, ret; /* Search for the handler */ for (i = 0; i < ARRAY_SIZE(ncsi_cmd_handlers); i++) { if (ncsi_cmd_handlers[i].type == nca->type) { if (ncsi_cmd_handlers[i].handler) nch = &ncsi_cmd_handlers[i]; else nch = NULL; break; } } if (!nch) { netdev_err(nca->ndp->ndev.dev, "Cannot send packet with type 0x%02x\n", nca->type); return -ENOENT; } /* Get packet payload length and allocate the request */ nca->payload = nch->payload; nr = ncsi_alloc_command(nca); if (!nr) return -ENOMEM; /* Prepare the packet */ nca->id = nr->id; ret = nch->handler(nr->cmd, nca); if (ret) { ncsi_free_request(nr); return ret; } /* Fill the ethernet header */ eh = skb_push(nr->cmd, sizeof(*eh)); eh->h_proto = htons(ETH_P_NCSI); eth_broadcast_addr(eh->h_dest); eth_broadcast_addr(eh->h_source); /* Start the timer for the request that might not have * corresponding response. Given NCSI is an internal * connection a 1 second delay should be sufficient. */ nr->enabled = true; mod_timer(&nr->timer, jiffies + 1 * HZ); /* Send NCSI packet */ skb_get(nr->cmd); ret = dev_queue_xmit(nr->cmd); if (ret < 0) { ncsi_free_request(nr); return ret; } return 0; }
/* hard_start_xmit function for data interfaces (wlan#, wlan#wds#, wlan#sta) * Convert Ethernet header into a suitable IEEE 802.11 header depending on * device configuration. */ netdev_tx_t hostap_data_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct hostap_interface *iface; local_info_t *local; int need_headroom, need_tailroom = 0; struct ieee80211_hdr hdr; u16 fc, ethertype = 0; enum { WDS_NO = 0, WDS_OWN_FRAME, WDS_COMPLIANT_FRAME } use_wds = WDS_NO; u8 *encaps_data; int hdr_len, encaps_len, skip_header_bytes; int to_assoc_ap = 0; struct hostap_skb_tx_data *meta; iface = netdev_priv(dev); local = iface->local; if (skb->len < ETH_HLEN) { printk(KERN_DEBUG "%s: hostap_data_start_xmit: short skb " "(len=%d)\n", dev->name, skb->len); kfree_skb(skb); return NETDEV_TX_OK; } if (local->ddev != dev) { use_wds = (local->iw_mode == IW_MODE_MASTER && !(local->wds_type & HOSTAP_WDS_STANDARD_FRAME)) ? WDS_OWN_FRAME : WDS_COMPLIANT_FRAME; if (dev == local->stadev) { to_assoc_ap = 1; use_wds = WDS_NO; } else if (dev == local->apdev) { printk(KERN_DEBUG "%s: prism2_tx: trying to use " "AP device with Ethernet net dev\n", dev->name); kfree_skb(skb); return NETDEV_TX_OK; } } else { if (local->iw_mode == IW_MODE_REPEAT) { printk(KERN_DEBUG "%s: prism2_tx: trying to use " "non-WDS link in Repeater mode\n", dev->name); kfree_skb(skb); return NETDEV_TX_OK; } else if (local->iw_mode == IW_MODE_INFRA && (local->wds_type & HOSTAP_WDS_AP_CLIENT) && !ether_addr_equal(skb->data + ETH_ALEN, dev->dev_addr)) { /* AP client mode: send frames with foreign src addr * using 4-addr WDS frames */ use_wds = WDS_COMPLIANT_FRAME; } } /* Incoming skb->data: dst_addr[6], src_addr[6], proto[2], payload * ==> * Prism2 TX frame with 802.11 header: * txdesc (address order depending on used mode; includes dst_addr and * src_addr), possible encapsulation (RFC1042/Bridge-Tunnel; * proto[2], payload {, possible addr4[6]} */ ethertype = (skb->data[12] << 8) | skb->data[13]; memset(&hdr, 0, sizeof(hdr)); /* Length of data after IEEE 802.11 header */ encaps_data = NULL; encaps_len = 0; skip_header_bytes = ETH_HLEN; if (ethertype == ETH_P_AARP || ethertype == ETH_P_IPX) { encaps_data = bridge_tunnel_header; encaps_len = sizeof(bridge_tunnel_header); skip_header_bytes -= 2; } else if (ethertype >= 0x600) { encaps_data = rfc1042_header; encaps_len = sizeof(rfc1042_header); skip_header_bytes -= 2; } fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA; hdr_len = IEEE80211_DATA_HDR3_LEN; if (use_wds != WDS_NO) { /* Note! Prism2 station firmware has problems with sending real * 802.11 frames with four addresses; until these problems can * be fixed or worked around, 4-addr frames needed for WDS are * using incompatible format: FromDS flag is not set and the * fourth address is added after the frame payload; it is * assumed, that the receiving station knows how to handle this * frame format */ if (use_wds == WDS_COMPLIANT_FRAME) { fc |= IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS; /* From&To DS: Addr1 = RA, Addr2 = TA, Addr3 = DA, * Addr4 = SA */ skb_copy_from_linear_data_offset(skb, ETH_ALEN, &hdr.addr4, ETH_ALEN); hdr_len += ETH_ALEN; } else { /* bogus 4-addr format to workaround Prism2 station * f/w bug */ fc |= IEEE80211_FCTL_TODS; /* From DS: Addr1 = DA (used as RA), * Addr2 = BSSID (used as TA), Addr3 = SA (used as DA), */ /* SA from skb->data + ETH_ALEN will be added after * frame payload; use hdr.addr4 as a temporary buffer */ skb_copy_from_linear_data_offset(skb, ETH_ALEN, &hdr.addr4, ETH_ALEN); need_tailroom += ETH_ALEN; } /* send broadcast and multicast frames to broadcast RA, if * configured; otherwise, use unicast RA of the WDS link */ if ((local->wds_type & HOSTAP_WDS_BROADCAST_RA) && is_multicast_ether_addr(skb->data)) eth_broadcast_addr(hdr.addr1); else if (iface->type == HOSTAP_INTERFACE_WDS) memcpy(&hdr.addr1, iface->u.wds.remote_addr, ETH_ALEN); else memcpy(&hdr.addr1, local->bssid, ETH_ALEN); memcpy(&hdr.addr2, dev->dev_addr, ETH_ALEN); skb_copy_from_linear_data(skb, &hdr.addr3, ETH_ALEN); } else if (local->iw_mode == IW_MODE_MASTER && !to_assoc_ap) { fc |= IEEE80211_FCTL_FROMDS; /* From DS: Addr1 = DA, Addr2 = BSSID, Addr3 = SA */ skb_copy_from_linear_data(skb, &hdr.addr1, ETH_ALEN); memcpy(&hdr.addr2, dev->dev_addr, ETH_ALEN); skb_copy_from_linear_data_offset(skb, ETH_ALEN, &hdr.addr3, ETH_ALEN); } else if (local->iw_mode == IW_MODE_INFRA || to_assoc_ap) { fc |= IEEE80211_FCTL_TODS; /* To DS: Addr1 = BSSID, Addr2 = SA, Addr3 = DA */ memcpy(&hdr.addr1, to_assoc_ap ? local->assoc_ap_addr : local->bssid, ETH_ALEN); skb_copy_from_linear_data_offset(skb, ETH_ALEN, &hdr.addr2, ETH_ALEN); skb_copy_from_linear_data(skb, &hdr.addr3, ETH_ALEN); } else if (local->iw_mode == IW_MODE_ADHOC) { /* not From/To DS: Addr1 = DA, Addr2 = SA, Addr3 = BSSID */ skb_copy_from_linear_data(skb, &hdr.addr1, ETH_ALEN); skb_copy_from_linear_data_offset(skb, ETH_ALEN, &hdr.addr2, ETH_ALEN); memcpy(&hdr.addr3, local->bssid, ETH_ALEN); } hdr.frame_control = cpu_to_le16(fc); skb_pull(skb, skip_header_bytes); need_headroom = local->func->need_tx_headroom + hdr_len + encaps_len; if (skb_tailroom(skb) < need_tailroom) { skb = skb_unshare(skb, GFP_ATOMIC); if (skb == NULL) { iface->stats.tx_dropped++; return NETDEV_TX_OK; } if (pskb_expand_head(skb, need_headroom, need_tailroom, GFP_ATOMIC)) { kfree_skb(skb); iface->stats.tx_dropped++; return NETDEV_TX_OK; } } else if (skb_headroom(skb) < need_headroom) { struct sk_buff *tmp = skb; skb = skb_realloc_headroom(skb, need_headroom); kfree_skb(tmp); if (skb == NULL) { iface->stats.tx_dropped++; return NETDEV_TX_OK; } } else { skb = skb_unshare(skb, GFP_ATOMIC); if (skb == NULL) { iface->stats.tx_dropped++; return NETDEV_TX_OK; } } if (encaps_data) memcpy(skb_push(skb, encaps_len), encaps_data, encaps_len); memcpy(skb_push(skb, hdr_len), &hdr, hdr_len); if (use_wds == WDS_OWN_FRAME) { memcpy(skb_put(skb, ETH_ALEN), &hdr.addr4, ETH_ALEN); } iface->stats.tx_packets++; iface->stats.tx_bytes += skb->len; skb_reset_mac_header(skb); meta = (struct hostap_skb_tx_data *) skb->cb; memset(meta, 0, sizeof(*meta)); meta->magic = HOSTAP_SKB_TX_DATA_MAGIC; if (use_wds) meta->flags |= HOSTAP_TX_FLAGS_WDS; meta->ethertype = ethertype; meta->iface = iface; /* Send IEEE 802.11 encapsulated frame using the master radio device */ skb->dev = local->dev; dev_queue_xmit(skb); return NETDEV_TX_OK; }
/* * This function initializes the adapter structure and sets default * values to the members of adapter. * * This also initializes the WMM related parameters in the driver private * structures. */ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter) { struct mwifiex_opt_sleep_confirm *sleep_cfm_buf = NULL; skb_put(adapter->sleep_cfm, sizeof(struct mwifiex_opt_sleep_confirm)); adapter->cmd_sent = false; if (adapter->iface_type == MWIFIEX_SDIO) adapter->data_sent = true; else adapter->data_sent = false; adapter->cmd_resp_received = false; adapter->event_received = false; adapter->data_received = false; adapter->surprise_removed = false; adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING; adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM; adapter->ps_state = PS_STATE_AWAKE; adapter->need_to_wakeup = false; adapter->scan_mode = HostCmd_BSS_MODE_ANY; adapter->specific_scan_time = MWIFIEX_SPECIFIC_SCAN_CHAN_TIME; adapter->active_scan_time = MWIFIEX_ACTIVE_SCAN_CHAN_TIME; adapter->passive_scan_time = MWIFIEX_PASSIVE_SCAN_CHAN_TIME; adapter->scan_chan_gap_time = MWIFIEX_DEF_SCAN_CHAN_GAP_TIME; adapter->scan_probes = 1; adapter->multiple_dtim = 1; adapter->local_listen_interval = 0; /* default value in firmware will be used */ adapter->is_deep_sleep = false; adapter->delay_null_pkt = false; adapter->delay_to_ps = 1000; adapter->enhanced_ps_mode = PS_MODE_AUTO; adapter->gen_null_pkt = false; /* Disable NULL Pkg generation by default */ adapter->pps_uapsd_mode = false; /* Disable pps/uapsd mode by default */ adapter->pm_wakeup_card_req = false; adapter->pm_wakeup_fw_try = false; adapter->curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K; adapter->is_hs_configured = false; adapter->hs_cfg.conditions = cpu_to_le32(HS_CFG_COND_DEF); adapter->hs_cfg.gpio = HS_CFG_GPIO_DEF; adapter->hs_cfg.gap = HS_CFG_GAP_DEF; adapter->hs_activated = false; memset(adapter->event_body, 0, sizeof(adapter->event_body)); adapter->hw_dot_11n_dev_cap = 0; adapter->hw_dev_mcs_support = 0; adapter->sec_chan_offset = 0; adapter->adhoc_11n_enabled = false; mwifiex_wmm_init(adapter); sleep_cfm_buf = (struct mwifiex_opt_sleep_confirm *) adapter->sleep_cfm->data; memset(sleep_cfm_buf, 0, adapter->sleep_cfm->len); sleep_cfm_buf->command = cpu_to_le16(HostCmd_CMD_802_11_PS_MODE_ENH); sleep_cfm_buf->size = cpu_to_le16(adapter->sleep_cfm->len); sleep_cfm_buf->result = 0; sleep_cfm_buf->action = cpu_to_le16(SLEEP_CONFIRM); sleep_cfm_buf->resp_ctrl = cpu_to_le16(RESP_NEEDED); memset(&adapter->sleep_params, 0, sizeof(adapter->sleep_params)); memset(&adapter->sleep_period, 0, sizeof(adapter->sleep_period)); adapter->tx_lock_flag = false; adapter->null_pkt_interval = 0; adapter->fw_bands = 0; adapter->config_bands = 0; adapter->adhoc_start_band = 0; adapter->scan_channels = NULL; adapter->fw_release_number = 0; adapter->fw_cap_info = 0; memset(&adapter->upld_buf, 0, sizeof(adapter->upld_buf)); adapter->event_cause = 0; adapter->region_code = 0; adapter->bcn_miss_time_out = DEFAULT_BCN_MISS_TIMEOUT; adapter->adhoc_awake_period = 0; memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter)); adapter->arp_filter_size = 0; adapter->max_mgmt_ie_index = MAX_MGMT_IE_INDEX; adapter->key_api_major_ver = 0; adapter->key_api_minor_ver = 0; eth_broadcast_addr(adapter->perm_addr); adapter->iface_limit.sta_intf = MWIFIEX_MAX_STA_NUM; adapter->iface_limit.uap_intf = MWIFIEX_MAX_UAP_NUM; adapter->iface_limit.p2p_intf = MWIFIEX_MAX_P2P_NUM; adapter->active_scan_triggered = false; setup_timer(&adapter->wakeup_timer, wakeup_timer_fn, (unsigned long)adapter); }