1/** 2 * This file contains the handling of RX in wlan driver. 3 */ 4#include <linux/etherdevice.h> 5#include <linux/slab.h> 6#include <linux/types.h> 7#include <net/cfg80211.h> 8 9#include "defs.h" 10#include "host.h" 11#include "radiotap.h" 12#include "decl.h" 13#include "dev.h" 14 15struct eth803hdr { 16 u8 dest_addr[6]; 17 u8 src_addr[6]; 18 u16 h803_len; 19} __packed; 20 21struct rfc1042hdr { 22 u8 llc_dsap; 23 u8 llc_ssap; 24 u8 llc_ctrl; 25 u8 snap_oui[3]; 26 u16 snap_type; 27} __packed; 28 29struct rxpackethdr { 30 struct eth803hdr eth803_hdr; 31 struct rfc1042hdr rfc1042_hdr; 32} __packed; 33 34struct rx80211packethdr { 35 struct rxpd rx_pd; 36 void *eth80211_hdr; 37} __packed; 38 39static int process_rxed_802_11_packet(struct lbs_private *priv, 40 struct sk_buff *skb); 41 42/** 43 * @brief This function processes received packet and forwards it 44 * to kernel/upper layer 45 * 46 * @param priv A pointer to struct lbs_private 47 * @param skb A pointer to skb which includes the received packet 48 * @return 0 or -1 49 */ 50int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb) 51{ 52 int ret = 0; 53 struct net_device *dev = priv->dev; 54 struct rxpackethdr *p_rx_pkt; 55 struct rxpd *p_rx_pd; 56 int hdrchop; 57 struct ethhdr *p_ethhdr; 58 const u8 rfc1042_eth_hdr[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 }; 59 60 lbs_deb_enter(LBS_DEB_RX); 61 62 BUG_ON(!skb); 63 64 skb->ip_summed = CHECKSUM_NONE; 65 66 if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR) 67 return process_rxed_802_11_packet(priv, skb); 68 69 p_rx_pd = (struct rxpd *) skb->data; 70 p_rx_pkt = (struct rxpackethdr *) ((u8 *)p_rx_pd + 71 le32_to_cpu(p_rx_pd->pkt_ptr)); 72 73 dev = lbs_mesh_set_dev(priv, dev, p_rx_pd); 74 75 lbs_deb_hex(LBS_DEB_RX, "RX Data: Before chop rxpd", skb->data, 76 min_t(unsigned int, skb->len, 100)); 77 78 if (skb->len < (ETH_HLEN + 8 + sizeof(struct rxpd))) { 79 lbs_deb_rx("rx err: frame received with bad length\n"); 80 dev->stats.rx_length_errors++; 81 ret = 0; 82 dev_kfree_skb(skb); 83 goto done; 84 } 85 86 lbs_deb_rx("rx data: skb->len - pkt_ptr = %d-%zd = %zd\n", 87 skb->len, (size_t)le32_to_cpu(p_rx_pd->pkt_ptr), 88 skb->len - (size_t)le32_to_cpu(p_rx_pd->pkt_ptr)); 89 90 lbs_deb_hex(LBS_DEB_RX, "RX Data: Dest", p_rx_pkt->eth803_hdr.dest_addr, 91 sizeof(p_rx_pkt->eth803_hdr.dest_addr)); 92 lbs_deb_hex(LBS_DEB_RX, "RX Data: Src", p_rx_pkt->eth803_hdr.src_addr, 93 sizeof(p_rx_pkt->eth803_hdr.src_addr)); 94 95 if (memcmp(&p_rx_pkt->rfc1042_hdr, 96 rfc1042_eth_hdr, sizeof(rfc1042_eth_hdr)) == 0) { 97 /* 98 * Replace the 803 header and rfc1042 header (llc/snap) with an 99 * EthernetII header, keep the src/dst and snap_type (ethertype) 100 * 101 * The firmware only passes up SNAP frames converting 102 * all RX Data from 802.11 to 802.2/LLC/SNAP frames. 103 * 104 * To create the Ethernet II, just move the src, dst address right 105 * before the snap_type. 106 */ 107 p_ethhdr = (struct ethhdr *) 108 ((u8 *) &p_rx_pkt->eth803_hdr 109 + sizeof(p_rx_pkt->eth803_hdr) + sizeof(p_rx_pkt->rfc1042_hdr) 110 - sizeof(p_rx_pkt->eth803_hdr.dest_addr) 111 - sizeof(p_rx_pkt->eth803_hdr.src_addr) 112 - sizeof(p_rx_pkt->rfc1042_hdr.snap_type)); 113 114 memcpy(p_ethhdr->h_source, p_rx_pkt->eth803_hdr.src_addr, 115 sizeof(p_ethhdr->h_source)); 116 memcpy(p_ethhdr->h_dest, p_rx_pkt->eth803_hdr.dest_addr, 117 sizeof(p_ethhdr->h_dest)); 118 119 /* Chop off the rxpd + the excess memory from the 802.2/llc/snap header 120 * that was removed 121 */ 122 hdrchop = (u8 *)p_ethhdr - (u8 *)p_rx_pd; 123 } else { 124 lbs_deb_hex(LBS_DEB_RX, "RX Data: LLC/SNAP", 125 (u8 *) &p_rx_pkt->rfc1042_hdr, 126 sizeof(p_rx_pkt->rfc1042_hdr)); 127 128 /* Chop off the rxpd */ 129 hdrchop = (u8 *)&p_rx_pkt->eth803_hdr - (u8 *)p_rx_pd; 130 } 131 132 /* Chop off the leading header bytes so the skb points to the start of 133 * either the reconstructed EthII frame or the 802.2/llc/snap frame 134 */ 135 skb_pull(skb, hdrchop); 136 137 priv->cur_rate = lbs_fw_index_to_data_rate(p_rx_pd->rx_rate); 138 139 lbs_deb_rx("rx data: size of actual packet %d\n", skb->len); 140 dev->stats.rx_bytes += skb->len; 141 dev->stats.rx_packets++; 142 143 skb->protocol = eth_type_trans(skb, dev); 144 if (in_interrupt()) 145 netif_rx(skb); 146 else 147 netif_rx_ni(skb); 148 149 ret = 0; 150done: 151 lbs_deb_leave_args(LBS_DEB_RX, "ret %d", ret); 152 return ret; 153} 154EXPORT_SYMBOL_GPL(lbs_process_rxed_packet); 155 156/** 157 * @brief This function converts Tx/Rx rates from the Marvell WLAN format 158 * (see Table 2 in Section 3.1) to IEEE80211_RADIOTAP_RATE units (500 Kb/s) 159 * 160 * @param rate Input rate 161 * @return Output Rate (0 if invalid) 162 */ 163static u8 convert_mv_rate_to_radiotap(u8 rate) 164{ 165 switch (rate) { 166 case 0: /* 1 Mbps */ 167 return 2; 168 case 1: /* 2 Mbps */ 169 return 4; 170 case 2: /* 5.5 Mbps */ 171 return 11; 172 case 3: /* 11 Mbps */ 173 return 22; 174 /* case 4: reserved */ 175 case 5: /* 6 Mbps */ 176 return 12; 177 case 6: /* 9 Mbps */ 178 return 18; 179 case 7: /* 12 Mbps */ 180 return 24; 181 case 8: /* 18 Mbps */ 182 return 36; 183 case 9: /* 24 Mbps */ 184 return 48; 185 case 10: /* 36 Mbps */ 186 return 72; 187 case 11: /* 48 Mbps */ 188 return 96; 189 case 12: /* 54 Mbps */ 190 return 108; 191 } 192 lbs_pr_alert("Invalid Marvell WLAN rate %i\n", rate); 193 return 0; 194} 195 196/** 197 * @brief This function processes a received 802.11 packet and forwards it 198 * to kernel/upper layer 199 * 200 * @param priv A pointer to struct lbs_private 201 * @param skb A pointer to skb which includes the received packet 202 * @return 0 or -1 203 */ 204static int process_rxed_802_11_packet(struct lbs_private *priv, 205 struct sk_buff *skb) 206{ 207 int ret = 0; 208 struct net_device *dev = priv->dev; 209 struct rx80211packethdr *p_rx_pkt; 210 struct rxpd *prxpd; 211 struct rx_radiotap_hdr radiotap_hdr; 212 struct rx_radiotap_hdr *pradiotap_hdr; 213 214 lbs_deb_enter(LBS_DEB_RX); 215 216 p_rx_pkt = (struct rx80211packethdr *) skb->data; 217 prxpd = &p_rx_pkt->rx_pd; 218 219 /* lbs_deb_hex(LBS_DEB_RX, "RX Data: Before chop rxpd", skb->data, min(skb->len, 100)); */ 220 221 if (skb->len < (ETH_HLEN + 8 + sizeof(struct rxpd))) { 222 lbs_deb_rx("rx err: frame received with bad length\n"); 223 dev->stats.rx_length_errors++; 224 ret = -EINVAL; 225 kfree_skb(skb); 226 goto done; 227 } 228 229 lbs_deb_rx("rx data: skb->len-sizeof(RxPd) = %d-%zd = %zd\n", 230 skb->len, sizeof(struct rxpd), skb->len - sizeof(struct rxpd)); 231 232 /* create the exported radio header */ 233 234 /* radiotap header */ 235 memset(&radiotap_hdr, 0, sizeof(radiotap_hdr)); 236 radiotap_hdr.hdr.it_len = cpu_to_le16 (sizeof(struct rx_radiotap_hdr)); 237 radiotap_hdr.hdr.it_present = cpu_to_le32 (RX_RADIOTAP_PRESENT); 238 radiotap_hdr.rate = convert_mv_rate_to_radiotap(prxpd->rx_rate); 239 radiotap_hdr.antsignal = prxpd->snr + prxpd->nf; 240 241 /* chop the rxpd */ 242 skb_pull(skb, sizeof(struct rxpd)); 243 244 /* add space for the new radio header */ 245 if ((skb_headroom(skb) < sizeof(struct rx_radiotap_hdr)) && 246 pskb_expand_head(skb, sizeof(struct rx_radiotap_hdr), 0, GFP_ATOMIC)) { 247 lbs_pr_alert("%s: couldn't pskb_expand_head\n", __func__); 248 ret = -ENOMEM; 249 kfree_skb(skb); 250 goto done; 251 } 252 253 pradiotap_hdr = (void *)skb_push(skb, sizeof(struct rx_radiotap_hdr)); 254 memcpy(pradiotap_hdr, &radiotap_hdr, sizeof(struct rx_radiotap_hdr)); 255 256 priv->cur_rate = lbs_fw_index_to_data_rate(prxpd->rx_rate); 257 258 lbs_deb_rx("rx data: size of actual packet %d\n", skb->len); 259 dev->stats.rx_bytes += skb->len; 260 dev->stats.rx_packets++; 261 262 skb->protocol = eth_type_trans(skb, priv->dev); 263 264 if (in_interrupt()) 265 netif_rx(skb); 266 else 267 netif_rx_ni(skb); 268 269 ret = 0; 270 271done: 272 lbs_deb_leave_args(LBS_DEB_RX, "ret %d", ret); 273 return ret; 274} 275