tx.c revision d43c36dc6b357fa1806800f18aa30123c747a6d1
1/** 2 * This file contains the handling of TX in wlan driver. 3 */ 4#include <linux/netdevice.h> 5#include <linux/etherdevice.h> 6#include <linux/sched.h> 7 8#include "hostcmd.h" 9#include "radiotap.h" 10#include "decl.h" 11#include "defs.h" 12#include "dev.h" 13#include "wext.h" 14 15/** 16 * @brief This function converts Tx/Rx rates from IEEE80211_RADIOTAP_RATE 17 * units (500 Kb/s) into Marvell WLAN format (see Table 8 in Section 3.2.1) 18 * 19 * @param rate Input rate 20 * @return Output Rate (0 if invalid) 21 */ 22static u32 convert_radiotap_rate_to_mv(u8 rate) 23{ 24 switch (rate) { 25 case 2: /* 1 Mbps */ 26 return 0 | (1 << 4); 27 case 4: /* 2 Mbps */ 28 return 1 | (1 << 4); 29 case 11: /* 5.5 Mbps */ 30 return 2 | (1 << 4); 31 case 22: /* 11 Mbps */ 32 return 3 | (1 << 4); 33 case 12: /* 6 Mbps */ 34 return 4 | (1 << 4); 35 case 18: /* 9 Mbps */ 36 return 5 | (1 << 4); 37 case 24: /* 12 Mbps */ 38 return 6 | (1 << 4); 39 case 36: /* 18 Mbps */ 40 return 7 | (1 << 4); 41 case 48: /* 24 Mbps */ 42 return 8 | (1 << 4); 43 case 72: /* 36 Mbps */ 44 return 9 | (1 << 4); 45 case 96: /* 48 Mbps */ 46 return 10 | (1 << 4); 47 case 108: /* 54 Mbps */ 48 return 11 | (1 << 4); 49 } 50 return 0; 51} 52 53/** 54 * @brief This function checks the conditions and sends packet to IF 55 * layer if everything is ok. 56 * 57 * @param priv A pointer to struct lbs_private structure 58 * @param skb A pointer to skb which includes TX packet 59 * @return 0 or -1 60 */ 61netdev_tx_t lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) 62{ 63 unsigned long flags; 64 struct lbs_private *priv = dev->ml_priv; 65 struct txpd *txpd; 66 char *p802x_hdr; 67 uint16_t pkt_len; 68 netdev_tx_t ret = NETDEV_TX_OK; 69 70 lbs_deb_enter(LBS_DEB_TX); 71 72 /* We need to protect against the queues being restarted before 73 we get round to stopping them */ 74 spin_lock_irqsave(&priv->driver_lock, flags); 75 76 if (priv->surpriseremoved) 77 goto free; 78 79 if (!skb->len || (skb->len > MRVDRV_ETH_TX_PACKET_BUFFER_SIZE)) { 80 lbs_deb_tx("tx err: skb length %d 0 or > %zd\n", 81 skb->len, MRVDRV_ETH_TX_PACKET_BUFFER_SIZE); 82 /* We'll never manage to send this one; drop it and return 'OK' */ 83 84 dev->stats.tx_dropped++; 85 dev->stats.tx_errors++; 86 goto free; 87 } 88 89 90 netif_stop_queue(priv->dev); 91 if (priv->mesh_dev) 92 netif_stop_queue(priv->mesh_dev); 93 94 if (priv->tx_pending_len) { 95 /* This can happen if packets come in on the mesh and eth 96 device simultaneously -- there's no mutual exclusion on 97 hard_start_xmit() calls between devices. */ 98 lbs_deb_tx("Packet on %s while busy\n", dev->name); 99 ret = NETDEV_TX_BUSY; 100 goto unlock; 101 } 102 103 priv->tx_pending_len = -1; 104 spin_unlock_irqrestore(&priv->driver_lock, flags); 105 106 lbs_deb_hex(LBS_DEB_TX, "TX Data", skb->data, min_t(unsigned int, skb->len, 100)); 107 108 txpd = (void *)priv->tx_pending_buf; 109 memset(txpd, 0, sizeof(struct txpd)); 110 111 p802x_hdr = skb->data; 112 pkt_len = skb->len; 113 114 if (dev == priv->rtap_net_dev) { 115 struct tx_radiotap_hdr *rtap_hdr = (void *)skb->data; 116 117 /* set txpd fields from the radiotap header */ 118 txpd->tx_control = cpu_to_le32(convert_radiotap_rate_to_mv(rtap_hdr->rate)); 119 120 /* skip the radiotap header */ 121 p802x_hdr += sizeof(*rtap_hdr); 122 pkt_len -= sizeof(*rtap_hdr); 123 124 /* copy destination address from 802.11 header */ 125 memcpy(txpd->tx_dest_addr_high, p802x_hdr + 4, ETH_ALEN); 126 } else { 127 /* copy destination address from 802.3 header */ 128 memcpy(txpd->tx_dest_addr_high, p802x_hdr, ETH_ALEN); 129 } 130 131 txpd->tx_packet_length = cpu_to_le16(pkt_len); 132 txpd->tx_packet_location = cpu_to_le32(sizeof(struct txpd)); 133 134 if (dev == priv->mesh_dev) { 135 if (priv->mesh_fw_ver == MESH_FW_OLD) 136 txpd->tx_control |= cpu_to_le32(TxPD_MESH_FRAME); 137 else if (priv->mesh_fw_ver == MESH_FW_NEW) 138 txpd->u.bss.bss_num = MESH_IFACE_ID; 139 } 140 141 lbs_deb_hex(LBS_DEB_TX, "txpd", (u8 *) &txpd, sizeof(struct txpd)); 142 143 lbs_deb_hex(LBS_DEB_TX, "Tx Data", (u8 *) p802x_hdr, le16_to_cpu(txpd->tx_packet_length)); 144 145 memcpy(&txpd[1], p802x_hdr, le16_to_cpu(txpd->tx_packet_length)); 146 147 spin_lock_irqsave(&priv->driver_lock, flags); 148 priv->tx_pending_len = pkt_len + sizeof(struct txpd); 149 150 lbs_deb_tx("%s lined up packet\n", __func__); 151 152 dev->stats.tx_packets++; 153 dev->stats.tx_bytes += skb->len; 154 155 dev->trans_start = jiffies; 156 157 if (priv->monitormode) { 158 /* Keep the skb to echo it back once Tx feedback is 159 received from FW */ 160 skb_orphan(skb); 161 162 /* Keep the skb around for when we get feedback */ 163 priv->currenttxskb = skb; 164 } else { 165 free: 166 dev_kfree_skb_any(skb); 167 } 168 unlock: 169 spin_unlock_irqrestore(&priv->driver_lock, flags); 170 wake_up(&priv->waitq); 171 172 lbs_deb_leave_args(LBS_DEB_TX, "ret %d", ret); 173 return ret; 174} 175 176/** 177 * @brief This function sends to the host the last transmitted packet, 178 * filling the radiotap headers with transmission information. 179 * 180 * @param priv A pointer to struct lbs_private structure 181 * @param status A 32 bit value containing transmission status. 182 * 183 * @returns void 184 */ 185void lbs_send_tx_feedback(struct lbs_private *priv, u32 try_count) 186{ 187 struct tx_radiotap_hdr *radiotap_hdr; 188 189 if (!priv->monitormode || priv->currenttxskb == NULL) 190 return; 191 192 radiotap_hdr = (struct tx_radiotap_hdr *)priv->currenttxskb->data; 193 194 radiotap_hdr->data_retries = try_count ? 195 (1 + priv->txretrycount - try_count) : 0; 196 197 priv->currenttxskb->protocol = eth_type_trans(priv->currenttxskb, 198 priv->rtap_net_dev); 199 netif_rx(priv->currenttxskb); 200 201 priv->currenttxskb = NULL; 202 203 if (priv->connect_status == LBS_CONNECTED) 204 netif_wake_queue(priv->dev); 205 206 if (priv->mesh_dev && (priv->mesh_connect_status == LBS_CONNECTED)) 207 netif_wake_queue(priv->mesh_dev); 208} 209EXPORT_SYMBOL_GPL(lbs_send_tx_feedback); 210