static void _rtl_tx_complete(struct urb *urb) { struct sk_buff *skb = (struct sk_buff *)urb->context; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct rtl_usb *rtlusb = (struct rtl_usb *)info->rate_driver_data[0]; struct ieee80211_hw *hw = usb_get_intfdata(rtlusb->intf); int err; if (unlikely(IS_USB_STOP(rtlusb))) return; err = _usb_tx_post(hw, urb, skb); if (err) { /* Ignore error and keep issuiing other urbs */ return; } }
/* Headroom is not adjusted. Caller should ensure that skb has sufficient * headroom in case the frame is encrypted. */ static void prepare_frame_for_deferred_tx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) { struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); skb_set_mac_header(skb, 0); skb_set_network_header(skb, 0); skb_set_transport_header(skb, 0); /* Send all internal mgmt frames on VO. Accordingly set TID to 7. */ skb_set_queue_mapping(skb, IEEE80211_AC_VO); skb->priority = 7; info->control.vif = &sdata->vif; ieee80211_set_qos_hdr(sdata, skb); }
static void p54spi_op_tx(struct ieee80211_hw *dev, struct sk_buff *skb) { struct p54s_priv *priv = dev->priv; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct p54_tx_info *mi = (struct p54_tx_info *) info->rate_driver_data; struct p54s_tx_info *di = (struct p54s_tx_info *) mi->data; unsigned long flags; BUILD_BUG_ON(sizeof(*di) > sizeof((mi->data))); spin_lock_irqsave(&priv->tx_lock, flags); list_add_tail(&di->tx_list, &priv->tx_pending); spin_unlock_irqrestore(&priv->tx_lock, flags); ieee80211_queue_work(priv->hw, &priv->work); }
/** * mesh_nexthop_resolve - lookup next hop; conditionally start path discovery * * @skb: 802.11 frame to be sent * @sdata: network subif the frame will be sent through * * Lookup next hop for given skb and start path discovery if no * forwarding information is found. * * Returns: 0 if the next hop was found and -ENOENT if the frame was queued. * skb is freeed here if no mpath could be allocated. */ int mesh_nexthop_resolve(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct mesh_path *mpath; struct sk_buff *skb_to_free = NULL; u8 *target_addr = hdr->addr3; int err = 0; /* Nulls are only sent to peers for PS and should be pre-addressed */ if (ieee80211_is_qos_nullfunc(hdr->frame_control)) return 0; rcu_read_lock(); err = mesh_nexthop_lookup(sdata, skb); if (!err) goto endlookup; /* no nexthop found, start resolving */ mpath = mesh_path_lookup(sdata, target_addr); if (!mpath) { mpath = mesh_path_add(sdata, target_addr); if (IS_ERR(mpath)) { mesh_path_discard_frame(sdata, skb); err = PTR_ERR(mpath); goto endlookup; } } if (!(mpath->flags & MESH_PATH_RESOLVING)) mesh_queue_preq(mpath, PREQ_Q_F_START); if (skb_queue_len(&mpath->frame_queue) >= MESH_FRAME_QUEUE_LEN) skb_to_free = skb_dequeue(&mpath->frame_queue); info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; ieee80211_set_qos_hdr(sdata, skb); skb_queue_tail(&mpath->frame_queue, skb); err = -ENOENT; if (skb_to_free) mesh_path_discard_frame(sdata, skb_to_free); endlookup: rcu_read_unlock(); return err; }
/** * tx_urb_complete - completes the execution of an URB * @urb: a URB * * This function is called if the URB has been transferred to a device or an * error has happened. */ static void tx_urb_complete(struct urb *urb) { int r; struct sk_buff *skb; struct ieee80211_tx_info *info; struct zd_usb *usb; struct zd_usb_tx *tx; skb = (struct sk_buff *)urb->context; info = IEEE80211_SKB_CB(skb); /* * grab 'usb' pointer before handing off the skb (since * it might be freed by zd_mac_tx_to_dev or mac80211) */ usb = &zd_hw_mac(info->rate_driver_data[0])->chip.usb; tx = &usb->tx; switch (urb->status) { case 0: break; case -ESHUTDOWN: case -EINVAL: case -ENODEV: case -ENOENT: case -ECONNRESET: case -EPIPE: dev_dbg_f(urb_dev(urb), "urb %p error %d\n", urb, urb->status); break; default: dev_dbg_f(urb_dev(urb), "urb %p error %d\n", urb, urb->status); goto resubmit; } free_urb: skb_unlink(skb, &usb->tx.submitted_skbs); zd_mac_tx_to_dev(skb, urb->status); usb_free_urb(urb); tx_dec_submitted_urbs(usb); return; resubmit: usb_anchor_urb(urb, &tx->submitted); r = usb_submit_urb(urb, GFP_ATOMIC); if (r) { usb_unanchor_urb(urb); dev_dbg_f(urb_dev(urb), "error resubmit urb %p %d\n", urb, r); goto free_urb; } }
static void rt2x00queue_create_tx_descriptor_seq(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb, struct txentry_desc *txdesc) { struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif); u16 seqno; if (!(tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)) return; __set_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags); if (!test_bit(REQUIRE_SW_SEQNO, &rt2x00dev->cap_flags)) { /* * rt2800 has a H/W (or F/W) bug, device incorrectly increase * seqno on retransmited data (non-QOS) frames. To workaround * the problem let's generate seqno in software if QOS is * disabled. */ if (test_bit(CONFIG_QOS_DISABLED, &rt2x00dev->flags)) __clear_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags); else /* H/W will generate sequence number */ return; } /* * The hardware is not able to insert a sequence number. Assign a * software generated one here. * * This is wrong because beacons are not getting sequence * numbers assigned properly. * * A secondary problem exists for drivers that cannot toggle * sequence counting per-frame, since those will override the * sequence counter given by mac80211. */ if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags)) seqno = atomic_add_return(0x10, &intf->seqno); else seqno = atomic_read(&intf->seqno); hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); hdr->seq_ctrl |= cpu_to_le16(seqno); }
static void adm8211_interrupt_tci(struct ieee80211_hw *dev) { struct adm8211_priv *priv = dev->priv; unsigned int dirty_tx; spin_lock(&priv->lock); for (dirty_tx = priv->dirty_tx; priv->cur_tx - dirty_tx; dirty_tx++) { unsigned int entry = dirty_tx % priv->tx_ring_size; u32 status = le32_to_cpu(priv->tx_ring[entry].status); struct ieee80211_tx_info *txi; struct adm8211_tx_ring_info *info; struct sk_buff *skb; if (status & TDES0_CONTROL_OWN || !(status & TDES0_CONTROL_DONE)) break; info = &priv->tx_buffers[entry]; skb = info->skb; txi = IEEE80211_SKB_CB(skb); /* TODO: check TDES0_STATUS_TUF and TDES0_STATUS_TRO */ pci_unmap_single(priv->pdev, info->mapping, info->skb->len, PCI_DMA_TODEVICE); ieee80211_tx_info_clear_status(txi); skb_pull(skb, sizeof(struct adm8211_tx_hdr)); memcpy(skb_push(skb, info->hdrlen), skb->cb, info->hdrlen); if (!(txi->flags & IEEE80211_TX_CTL_NO_ACK) && !(status & TDES0_STATUS_ES)) txi->flags |= IEEE80211_TX_STAT_ACK; ieee80211_tx_status_irqsafe(dev, skb); info->skb = NULL; } if (priv->cur_tx - dirty_tx < priv->tx_ring_size - 2) ieee80211_wake_queue(dev, 0); priv->dirty_tx = dirty_tx; spin_unlock(&priv->lock); }
void ieee80211s_update_metric(struct ieee80211_local *local, struct sta_info *stainfo, struct sk_buff *skb) { struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; int failed; if (!ieee80211_is_data(hdr->frame_control)) return; failed = !(txinfo->flags & IEEE80211_TX_STAT_ACK); /* moving average, scaled to 100 */ stainfo->fail_avg = ((80 * stainfo->fail_avg + 5) / 100 + 20 * failed); if (stainfo->fail_avg > 95) mesh_plink_broken(stainfo); }
static int ath9k_send_nullfunc(struct ath_wiphy *aphy, struct ieee80211_vif *vif, const u8 *bssid, int ps) { struct ath_softc *sc = aphy->sc; struct ath_tx_control txctl; struct sk_buff *skb; struct ieee80211_hdr *hdr; __le16 fc; struct ieee80211_tx_info *info; skb = dev_alloc_skb(24); if (skb == NULL) return -ENOMEM; hdr = (struct ieee80211_hdr *) skb_put(skb, 24); memset(hdr, 0, 24); fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS); if (ps) fc |= cpu_to_le16(IEEE80211_FCTL_PM); hdr->frame_control = fc; memcpy(hdr->addr1, bssid, ETH_ALEN); memcpy(hdr->addr2, aphy->hw->wiphy->perm_addr, ETH_ALEN); memcpy(hdr->addr3, bssid, ETH_ALEN); info = IEEE80211_SKB_CB(skb); memset(info, 0, sizeof(*info)); info->flags = IEEE80211_TX_CTL_REQ_TX_STATUS; info->control.vif = vif; info->control.rates[0].idx = 0; info->control.rates[0].count = 4; info->control.rates[1].idx = -1; memset(&txctl, 0, sizeof(struct ath_tx_control)); txctl.txq = &sc->tx.txq[sc->tx.hwq_map[ATH9K_WME_AC_VO]]; txctl.frame_type = ps ? ATH9K_INT_PAUSE : ATH9K_INT_UNPAUSE; if (ath_tx_start(aphy->hw, skb, &txctl) != 0) goto exit; return 0; exit: dev_kfree_skb_any(skb); return -1; }
static int pio_tx_frame(struct b43_pio_txqueue *q, struct sk_buff *skb) { struct b43_wldev *dev = q->dev; struct b43_wl *wl = dev->wl; struct b43_pio_txpacket *pack; u16 cookie; int err; unsigned int hdrlen; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); B43_WARN_ON(list_empty(&q->packets_list)); pack = list_entry(q->packets_list.next, struct b43_pio_txpacket, list); cookie = generate_cookie(q, pack); hdrlen = b43_txhdr_size(dev); err = b43_generate_txhdr(dev, (u8 *)&wl->txhdr, skb, info, cookie); if (err) return err; if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) { /* Tell the firmware about the cookie of the last * mcast frame, so it can clear the more-data bit in it. */ b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_MCASTCOOKIE, cookie); } pack->skb = skb; if (q->rev >= 8) pio_tx_frame_4byte_queue(pack, (const u8 *)&wl->txhdr, hdrlen); else pio_tx_frame_2byte_queue(pack, (const u8 *)&wl->txhdr, hdrlen); /* Remove it from the list of available packet slots. * It will be put back when we receive the status report. */ list_del(&pack->list); /* Update the queue statistics. */ q->buffer_used += roundup(skb->len + hdrlen, 4); q->free_packet_slots -= 1; return 0; }
static void brcms_ops_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, struct sk_buff *skb) { struct brcms_info *wl = hw->priv; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); spin_lock_bh(&wl->lock); if (!wl->pub->up) { brcms_err(wl->wlc->hw->d11core, "ops->tx called while down\n"); kfree_skb(skb); goto done; } if (brcms_c_sendpkt_mac80211(wl->wlc, skb, hw)) tx_info->rate_driver_data[0] = control->sta; done: spin_unlock_bh(&wl->lock); }
/** * mesh_nexthop_resolve - lookup next hop; conditionally start path discovery * * @skb: 802.11 frame to be sent * @sdata: network subif the frame will be sent through * * Lookup next hop for given skb and start path discovery if no * forwarding information is found. * * Returns: 0 if the next hop was found and -ENOENT if the frame was queued. * skb is freeed here if no mpath could be allocated. */ int mesh_nexthop_resolve(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct mesh_path *mpath; struct sk_buff *skb_to_free = NULL; u8 *target_addr = hdr->addr3; int err = 0; rcu_read_lock(); err = mesh_nexthop_lookup(skb, sdata); if (!err) goto endlookup; /* no nexthop found, start resolving */ mpath = mesh_path_lookup(target_addr, sdata); if (!mpath) { mesh_path_add(target_addr, sdata); mpath = mesh_path_lookup(target_addr, sdata); if (!mpath) { mesh_path_discard_frame(skb, sdata); err = -ENOSPC; goto endlookup; } } if (!(mpath->flags & MESH_PATH_RESOLVING)) mesh_queue_preq(mpath, PREQ_Q_F_START); if (skb_queue_len(&mpath->frame_queue) >= MESH_FRAME_QUEUE_LEN) skb_to_free = skb_dequeue(&mpath->frame_queue); info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; ieee80211_set_qos_hdr(sdata, skb); skb_queue_tail(&mpath->frame_queue, skb); err = -ENOENT; if (skb_to_free) mesh_path_discard_frame(skb_to_free, sdata); endlookup: rcu_read_unlock(); return err; }
static int pio_tx_frame(struct b43_pio_txqueue *q, struct sk_buff *skb) { struct b43_wldev *dev = q->dev; struct b43_wl *wl = dev->wl; struct b43_pio_txpacket *pack; u16 cookie; int err; unsigned int hdrlen; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct b43_txhdr *txhdr = (struct b43_txhdr *)wl->pio_scratchspace; B43_WARN_ON(list_empty(&q->packets_list)); pack = list_entry(q->packets_list.next, struct b43_pio_txpacket, list); cookie = generate_cookie(q, pack); hdrlen = b43_txhdr_size(dev); BUILD_BUG_ON(sizeof(wl->pio_scratchspace) < sizeof(struct b43_txhdr)); B43_WARN_ON(sizeof(wl->pio_scratchspace) < hdrlen); err = b43_generate_txhdr(dev, (u8 *)txhdr, skb, info, cookie); if (err) return err; if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) { b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_MCASTCOOKIE, cookie); } pack->skb = skb; if (q->rev >= 8) pio_tx_frame_4byte_queue(pack, (const u8 *)txhdr, hdrlen); else pio_tx_frame_2byte_queue(pack, (const u8 *)txhdr, hdrlen); list_del(&pack->list); q->buffer_used += roundup(skb->len + hdrlen, 4); q->free_packet_slots -= 1; return 0; }
ieee80211_tx_result ieee80211_crypto_aes_cmac_encrypt(struct ieee80211_tx_data *tx) { struct sk_buff *skb = tx->skb; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_key *key = tx->key; struct ieee80211_mmie *mmie; u8 *pn, aad[20]; int i; if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { /* hwaccel */ info->control.hw_key = &tx->key->conf; return 0; } if (WARN_ON(skb_tailroom(skb) < sizeof(*mmie))) return TX_DROP; mmie = (struct ieee80211_mmie *) skb_put(skb, sizeof(*mmie)); mmie->element_id = WLAN_EID_MMIE; mmie->length = sizeof(*mmie) - 2; mmie->key_id = cpu_to_le16(key->conf.keyidx); /* PN = PN + 1 */ pn = key->u.aes_cmac.tx_pn; for (i = sizeof(key->u.aes_cmac.tx_pn) - 1; i >= 0; i--) { pn[i]++; if (pn[i]) break; } bip_ipn_swap(mmie->sequence_number, pn); bip_aad(skb, aad); /* * MIC = AES-128-CMAC(IGTK, AAD || Management Frame Body || MMIE, 64) */ ieee80211_aes_cmac(key->u.aes_cmac.tfm, key->u.aes_cmac.tx_crypto_buf, aad, skb->data + 24, skb->len - 24, mmie->mic); return TX_CONTINUE; }
static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac, struct ieee80211_vif *vif) { struct ieee80211_hw *hw = arg; struct sk_buff *skb; struct ieee80211_tx_info *info; if (vif->type != IEEE80211_IF_TYPE_AP) return; skb = ieee80211_beacon_get(hw, vif); if (skb == NULL) return; info = IEEE80211_SKB_CB(skb); mac80211_hwsim_monitor_rx(hw, skb); mac80211_hwsim_tx_frame(hw, skb); dev_kfree_skb(skb); }
/* Headroom is not adjusted. Caller should ensure that skb has sufficient * headroom in case the frame is encrypted. */ static void prepare_frame_for_deferred_tx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) { struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; skb_reset_mac_header(skb); skb_reset_network_header(skb); skb_reset_transport_header(skb); /* Send all internal mgmt frames on VO. Accordingly set TID to 7. */ skb_set_queue_mapping(skb, IEEE80211_AC_VO); skb->priority = 7; info->control.vif = &sdata->vif; info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; ieee80211_set_qos_hdr(sdata, skb); ieee80211_mps_set_frame_flags(sdata, NULL, hdr); }
/** * ieee80211_set_qos_hdr - Fill in the QoS header if there is one. * * @sdata: local subif * @skb: packet to be updated */ void ieee80211_set_qos_hdr(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) { struct ieee80211_hdr *hdr = (void *)skb->data; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); u8 tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; u8 flags; u8 *p; if (!ieee80211_is_data_qos(hdr->frame_control)) return; p = ieee80211_get_qos_ctl(hdr); /* set up the first byte */ /* * preserve everything but the TID and ACK policy * (which we both write here) */ flags = *p & ~(IEEE80211_QOS_CTL_TID_MASK | IEEE80211_QOS_CTL_ACK_POLICY_MASK); if (is_multicast_ether_addr(hdr->addr1) || sdata->noack_map & BIT(tid)) { flags |= IEEE80211_QOS_CTL_ACK_POLICY_NOACK; info->flags |= IEEE80211_TX_CTL_NO_ACK; } *p = flags | tid; /* set up the second byte */ p++; if (ieee80211_vif_is_mesh(&sdata->vif)) { /* preserve RSPI and Mesh PS Level bit */ *p &= ((IEEE80211_QOS_CTL_RSPI | IEEE80211_QOS_CTL_MESH_PS_LEVEL) >> 8); /* Nulls don't have a mesh header (frame body) */ if (!ieee80211_is_qos_nullfunc(hdr->frame_control)) *p |= (IEEE80211_QOS_CTL_MESH_CONTROL_PRESENT >> 8); } else {
static bool zd_tx_timeout(struct zd_usb *usb) { struct zd_usb_tx *tx = &usb->tx; struct sk_buff_head *q = &tx->submitted_skbs; struct sk_buff *skb, *skbnext; struct ieee80211_tx_info *info; unsigned long flags, trans_start; bool have_timedout = false; spin_lock_irqsave(&q->lock, flags); skb_queue_walk_safe(q, skb, skbnext) { info = IEEE80211_SKB_CB(skb); trans_start = (unsigned long)info->rate_driver_data[1]; if (time_is_before_jiffies(trans_start + ZD_TX_TIMEOUT)) { have_timedout = true; break; } }
static void rate_control_pid_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, struct ieee80211_tx_rate_control *txrc) { struct sk_buff *skb = txrc->skb; struct ieee80211_supported_band *sband = txrc->sband; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct rc_pid_sta_info *spinfo = priv_sta; int rateidx; u16 fc; if (txrc->rts) info->control.rates[0].count = txrc->hw->conf.long_frame_max_tx_count; else info->control.rates[0].count = txrc->hw->conf.short_frame_max_tx_count; /* Send management frames and broadcast/multicast data using lowest * rate. */ fc = le16_to_cpu(hdr->frame_control); if (!sta || !spinfo || (fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA || is_multicast_ether_addr(hdr->addr1)) { info->control.rates[0].idx = rate_lowest_index(sband, sta); return; } rateidx = spinfo->txrate_idx; if (rateidx >= sband->n_bitrates) rateidx = sband->n_bitrates - 1; info->control.rates[0].idx = rateidx; #ifdef CONFIG_MAC80211_DEBUGFS rate_control_pid_event_tx_rate(&spinfo->events, rateidx, sband->bitrates[rateidx].bitrate); #endif }
static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw, struct sk_buff *tx_skb) { struct mac80211_hwsim_data *data = hw->priv; struct sk_buff *skb; struct hwsim_radiotap_hdr *hdr; u16 flags; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_skb); struct ieee80211_rate *txrate = ieee80211_get_tx_rate(hw, info); if (!netif_running(hwsim_mon)) return; skb = skb_copy_expand(tx_skb, sizeof(*hdr), 0, GFP_ATOMIC); if (skb == NULL) return; hdr = (struct hwsim_radiotap_hdr *) skb_push(skb, sizeof(*hdr)); hdr->hdr.it_version = PKTHDR_RADIOTAP_VERSION; hdr->hdr.it_pad = 0; hdr->hdr.it_len = cpu_to_le16(sizeof(*hdr)); hdr->hdr.it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) | (1 << IEEE80211_RADIOTAP_RATE) | (1 << IEEE80211_RADIOTAP_CHANNEL)); hdr->rt_flags = 0; hdr->rt_rate = txrate->bitrate / 5; hdr->rt_channel = cpu_to_le16(data->channel->center_freq); flags = IEEE80211_CHAN_2GHZ; if (txrate->flags & IEEE80211_RATE_ERP_G) flags |= IEEE80211_CHAN_OFDM; else flags |= IEEE80211_CHAN_CCK; hdr->rt_chbitmask = cpu_to_le16(flags); skb->dev = hwsim_mon; skb_set_mac_header(skb, 0); skb->ip_summed = CHECKSUM_UNNECESSARY; skb->pkt_type = PACKET_OTHERHOST; skb->protocol = htons(ETH_P_802_2); memset(skb->cb, 0, sizeof(skb->cb)); netif_rx(skb); }
int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb) { struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); if (tx_info->control.hw_key) { switch (tx_info->control.hw_key->cipher) { case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP104: return ATH9K_KEY_TYPE_WEP; case WLAN_CIPHER_SUITE_TKIP: return ATH9K_KEY_TYPE_TKIP; case WLAN_CIPHER_SUITE_CCMP: return ATH9K_KEY_TYPE_AES; default: break; } } return ATH9K_KEY_TYPE_CLEAR; }
void ieee80211s_update_metric(struct ieee80211_local *local, struct sta_info *sta, struct sk_buff *skb) { struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; int failed; if (!ieee80211_is_data(hdr->frame_control)) return; failed = !(txinfo->flags & IEEE80211_TX_STAT_ACK); /* moving average, scaled to 100. * feed failure as 100 and success as 0 */ ewma_mesh_fail_avg_add(&sta->mesh->fail_avg, failed * 100); if (ewma_mesh_fail_avg_read(&sta->mesh->fail_avg) > LINK_FAIL_THRESH) mesh_plink_broken(sta); }
/* caller must hold wl->mutex */ static int wl1271_tx_frame(struct wl1271 *wl, struct sk_buff *skb) { struct ieee80211_tx_info *info; u32 extra = 0; int ret = 0; u8 idx; if (!skb) return -EINVAL; info = IEEE80211_SKB_CB(skb); if (info->control.hw_key && info->control.hw_key->alg == ALG_TKIP) extra = WL1271_TKIP_IV_SPACE; if (info->control.hw_key) { idx = info->control.hw_key->hw_key_idx; /* FIXME: do we have to do this if we're not using WEP? */ if (unlikely(wl->default_key != idx)) { ret = wl1271_cmd_set_default_wep_key(wl, idx); if (ret < 0) return ret; } } ret = wl1271_tx_allocate(wl, skb, extra); if (ret < 0) return ret; ret = wl1271_tx_fill_hdr(wl, skb, extra, info); if (ret < 0) return ret; ret = wl1271_tx_send_packet(wl, skb, info); if (ret < 0) return ret; return ret; }
static void rate_control_pid_tx_status(void *priv, struct ieee80211_supported_band *sband, struct ieee80211_sta *sta, void *priv_sta, struct sk_buff *skb) { struct rc_pid_info *pinfo = priv; struct rc_pid_sta_info *spinfo = priv_sta; unsigned long period; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); if (!spinfo) return; /* Ignore all frames that were sent with a different rate than the rate * we currently advise mac80211 to use. */ if (info->tx_rate_idx != spinfo->txrate_idx) return; spinfo->tx_num_xmit++; #ifdef CONFIG_MAC80211_DEBUGFS rate_control_pid_event_tx_status(&spinfo->events, info); #endif /* We count frames that totally failed to be transmitted as two bad * frames, those that made it out but had some retries as one good and * one bad frame. */ if (info->status.excessive_retries) { spinfo->tx_num_failed += 2; spinfo->tx_num_xmit++; } else if (info->status.retry_count) { spinfo->tx_num_failed++; spinfo->tx_num_xmit++; } /* Update PID controller state. */ period = (HZ * pinfo->sampling_period + 500) / 1000; if (!period) period = 1; if (time_after(jiffies, spinfo->last_sample + period)) rate_control_pid_sample(pinfo, sband, sta, spinfo); }
static void reap_tx_dxes(struct wcn36xx *wcn, struct wcn36xx_dxe_ch *ch) { struct wcn36xx_dxe_ctl *ctl = ch->tail_blk_ctl; struct ieee80211_tx_info *info; while (ctl != ch->head_blk_ctl && !(ctl->desc->ctrl & WCN36XX_DXE_CTRL_VALID_MASK)) { if (ctl->skb) { dma_unmap_single(NULL, ctl->desc->src_addr_l, ctl->skb->len, DMA_TO_DEVICE); info = IEEE80211_SKB_CB(ctl->skb); if (!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS)) { /* Keep frame until TX status comes */ ieee80211_free_txskb(wcn->hw, ctl->skb); } ctl->skb = NULL; } ctl = ctl->next; } ch->tail_blk_ctl = ctl; }
static void reap_tx_dxes(struct wcn36xx *wcn, struct wcn36xx_dxe_ch *ch) { struct wcn36xx_dxe_ctl *ctl; struct ieee80211_tx_info *info; unsigned long flags; /* * Make at least one loop of do-while because in case ring is * completely full head and tail are pointing to the same element * and while-do will not make any cycles. */ spin_lock_irqsave(&ch->lock, flags); ctl = ch->tail_blk_ctl; do { if (READ_ONCE(ctl->desc->ctrl) & WCN36xx_DXE_CTRL_VLD) break; if (ctl->skb && READ_ONCE(ctl->desc->ctrl) & WCN36xx_DXE_CTRL_EOP) { dma_unmap_single(wcn->dev, ctl->desc->src_addr_l, ctl->skb->len, DMA_TO_DEVICE); info = IEEE80211_SKB_CB(ctl->skb); if (!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS)) { /* Keep frame until TX status comes */ ieee80211_free_txskb(wcn->hw, ctl->skb); } if (wcn->queues_stopped) { wcn->queues_stopped = false; ieee80211_wake_queues(wcn->hw); } ctl->skb = NULL; } ctl = ctl->next; } while (ctl != ch->head_blk_ctl); ch->tail_blk_ctl = ctl; spin_unlock_irqrestore(&ch->lock, flags); }
/** * zd_usb_tx: initiates transfer of a frame of the device * * @usb: the zd1211rw-private USB structure * @skb: a &struct sk_buff pointer * * This function tranmits a frame to the device. It doesn't wait for * completion. The frame must contain the control set and have all the * control set information available. * * The function returns 0 if the transfer has been successfully initiated. */ int zd_usb_tx(struct zd_usb *usb, struct sk_buff *skb) { int r; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct usb_device *udev = zd_usb_to_usbdev(usb); struct urb *urb; struct zd_usb_tx *tx = &usb->tx; if (!atomic_read(&tx->enabled)) { r = -ENOENT; goto out; } urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) { r = -ENOMEM; goto out; } usb_fill_bulk_urb(urb, udev, usb_sndbulkpipe(udev, EP_DATA_OUT), skb->data, skb->len, tx_urb_complete, skb); info->rate_driver_data[1] = (void *)jiffies; skb_queue_tail(&tx->submitted_skbs, skb); usb_anchor_urb(urb, &tx->submitted); r = usb_submit_urb(urb, GFP_ATOMIC); if (r) { dev_dbg_f(zd_usb_dev(usb), "error submit urb %p %d\n", urb, r); usb_unanchor_urb(urb); skb_unlink(skb, &tx->submitted_skbs); goto error; } tx_inc_submitted_urbs(usb); return 0; error: usb_free_urb(urb); out: return r; }
static int mac80211_hwsim_tx_frame(struct ieee80211_hw *hw, struct sk_buff *skb) { struct mac80211_hwsim_data *data = hw->priv; int i, ack = 0; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_rx_status rx_status; memset(&rx_status, 0, sizeof(rx_status)); /* TODO: set mactime */ rx_status.freq = data->channel->center_freq; rx_status.band = data->channel->band; rx_status.rate_idx = info->tx_rate_idx; /* TODO: simulate signal strength (and optional packet drop) */ /* Copy skb to all enabled radios that are on the current frequency */ for (i = 0; i < hwsim_radio_count; i++) { struct mac80211_hwsim_data *data2; struct sk_buff *nskb; if (hwsim_radios[i] == NULL || hwsim_radios[i] == hw) continue; data2 = hwsim_radios[i]->priv; if (!data2->started || !data2->radio_enabled || data->channel->center_freq != data2->channel->center_freq) continue; nskb = skb_copy(skb, GFP_ATOMIC); if (nskb == NULL) continue; if (memcmp(hdr->addr1, hwsim_radios[i]->wiphy->perm_addr, ETH_ALEN) == 0) ack = 1; ieee80211_rx_irqsafe(hwsim_radios[i], nskb, &rx_status); } return ack; }
static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int chain) { struct ieee80211_hw *hw = sc->hw; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); struct ath_tx_control txctl; int time_left; memset(&txctl, 0, sizeof(txctl)); txctl.txq = sc->tx.txq_map[WME_AC_BE]; memset(tx_info, 0, sizeof(*tx_info)); tx_info->band = hw->conf.channel->band; tx_info->flags |= IEEE80211_TX_CTL_NO_ACK; tx_info->control.rates[0].idx = 0; tx_info->control.rates[0].count = 1; tx_info->control.rates[0].flags = IEEE80211_TX_RC_MCS; tx_info->control.rates[1].idx = -1; init_completion(&sc->paprd_complete); txctl.paprd = BIT(chain); if (ath_tx_start(hw, skb, &txctl) != 0) { ath_dbg(common, ATH_DBG_CALIBRATE, "PAPRD TX failed\n"); dev_kfree_skb_any(skb); return false; } time_left = wait_for_completion_timeout(&sc->paprd_complete, msecs_to_jiffies(ATH_PAPRD_TIMEOUT)); if (!time_left) ath_dbg(common, ATH_DBG_CALIBRATE, "Timeout waiting for paprd training on TX chain %d\n", chain); return !!time_left; }
void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry, struct txentry_desc *txdesc) { struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); struct ieee80211_key_conf *hw_key = tx_info->control.hw_key; __set_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags); txdesc->cipher = rt2x00crypto_key_to_cipher(hw_key); if (hw_key->flags & IEEE80211_KEY_FLAG_PAIRWISE) __set_bit(ENTRY_TXD_ENCRYPT_PAIRWISE, &txdesc->flags); txdesc->key_idx = hw_key->hw_key_idx; txdesc->iv_offset = ieee80211_get_hdrlen_from_skb(entry->skb); if (!(hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV)) __set_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags); if (!(hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_MMIC)) __set_bit(ENTRY_TXD_ENCRYPT_MMIC, &txdesc->flags); }