|
@@ -97,6 +97,7 @@ static void mwifiex_uap_queue_bridged_pkt(struct mwifiex_private *priv,
|
|
|
struct mwifiex_txinfo *tx_info;
|
|
|
int hdr_chop;
|
|
|
struct timeval tv;
|
|
|
+ struct ethhdr *p_ethhdr;
|
|
|
u8 rfc1042_eth_hdr[ETH_ALEN] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
|
|
|
|
|
|
uap_rx_pd = (struct uap_rxpd *)(skb->data);
|
|
@@ -112,14 +113,36 @@ static void mwifiex_uap_queue_bridged_pkt(struct mwifiex_private *priv,
|
|
|
}
|
|
|
|
|
|
if (!memcmp(&rx_pkt_hdr->rfc1042_hdr,
|
|
|
- rfc1042_eth_hdr, sizeof(rfc1042_eth_hdr)))
|
|
|
+ rfc1042_eth_hdr, sizeof(rfc1042_eth_hdr))) {
|
|
|
+ /* Replace the 803 header and rfc1042 header (llc/snap) with
|
|
|
+ * an Ethernet II header, keep the src/dst and snap_type
|
|
|
+ * (ethertype).
|
|
|
+ *
|
|
|
+ * The firmware only passes up SNAP frames converting all RX
|
|
|
+ * data from 802.11 to 802.2/LLC/SNAP frames.
|
|
|
+ *
|
|
|
+ * To create the Ethernet II, just move the src, dst address
|
|
|
+ * right before the snap_type.
|
|
|
+ */
|
|
|
+ p_ethhdr = (struct ethhdr *)
|
|
|
+ ((u8 *)(&rx_pkt_hdr->eth803_hdr)
|
|
|
+ + sizeof(rx_pkt_hdr->eth803_hdr)
|
|
|
+ + sizeof(rx_pkt_hdr->rfc1042_hdr)
|
|
|
+ - sizeof(rx_pkt_hdr->eth803_hdr.h_dest)
|
|
|
+ - sizeof(rx_pkt_hdr->eth803_hdr.h_source)
|
|
|
+ - sizeof(rx_pkt_hdr->rfc1042_hdr.snap_type));
|
|
|
+ memcpy(p_ethhdr->h_source, rx_pkt_hdr->eth803_hdr.h_source,
|
|
|
+ sizeof(p_ethhdr->h_source));
|
|
|
+ memcpy(p_ethhdr->h_dest, rx_pkt_hdr->eth803_hdr.h_dest,
|
|
|
+ sizeof(p_ethhdr->h_dest));
|
|
|
/* Chop off the rxpd + the excess memory from
|
|
|
* 802.2/llc/snap header that was removed.
|
|
|
*/
|
|
|
- hdr_chop = (u8 *)eth_hdr - (u8 *)uap_rx_pd;
|
|
|
- else
|
|
|
+ hdr_chop = (u8 *)p_ethhdr - (u8 *)uap_rx_pd;
|
|
|
+ } else {
|
|
|
/* Chop off the rxpd */
|
|
|
hdr_chop = (u8 *)&rx_pkt_hdr->eth803_hdr - (u8 *)uap_rx_pd;
|
|
|
+ }
|
|
|
|
|
|
/* Chop off the leading header bytes so the it points
|
|
|
* to the start of either the reconstructed EthII frame
|