GNU Linux-libre 4.19.286-gnu1
[releases.git] / drivers / staging / rtl8188eu / os_dep / mon.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * RTL8188EU monitor interface
4  *
5  * Copyright (C) 2015 Jakub Sitnicki
6  */
7
8 #include <linux/ieee80211.h>
9 #include <linux/netdevice.h>
10 #include <net/cfg80211.h>
11
12 #include <drv_types.h>
13 #include <rtw_recv.h>
14 #include <rtw_xmit.h>
15 #include <mon.h>
16
17 /**
18  * unprotect_frame() - unset Protected flag and strip off IV and ICV/MIC
19  */
20 static void unprotect_frame(struct sk_buff *skb, int iv_len, int icv_len)
21 {
22         struct ieee80211_hdr *hdr;
23         int hdr_len;
24
25         hdr = (struct ieee80211_hdr *)skb->data;
26         hdr_len = ieee80211_hdrlen(hdr->frame_control);
27
28         if (skb->len < hdr_len + iv_len + icv_len)
29                 return;
30         if (!ieee80211_has_protected(hdr->frame_control))
31                 return;
32
33         hdr->frame_control &= ~cpu_to_le16(IEEE80211_FCTL_PROTECTED);
34
35         memmove(skb->data + iv_len, skb->data, hdr_len);
36         skb_pull(skb, iv_len);
37         skb_trim(skb, skb->len - icv_len);
38 }
39
40 static void mon_recv_decrypted(struct net_device *dev, const u8 *data,
41                                int data_len, int iv_len, int icv_len)
42 {
43         struct sk_buff *skb;
44
45         skb = netdev_alloc_skb(dev, data_len);
46         if (!skb)
47                 return;
48         skb_put_data(skb, data, data_len);
49
50         /*
51          * Frame data is not encrypted. Strip off protection so
52          * userspace doesn't think that it is.
53          */
54         unprotect_frame(skb, iv_len, icv_len);
55
56         skb->ip_summed = CHECKSUM_UNNECESSARY;
57         skb->protocol = eth_type_trans(skb, dev);
58         netif_rx(skb);
59 }
60
61 static void mon_recv_encrypted(struct net_device *dev, const u8 *data,
62                                int data_len)
63 {
64         if (net_ratelimit())
65                 netdev_info(dev, "Encrypted packets are not supported");
66 }
67
68 /**
69  * rtl88eu_mon_recv_hook() - forward received frame to the monitor interface
70  *
71  * Assumes that the frame contains an IV and an ICV/MIC, and that
72  * encrypt field in frame->attrib have been set accordingly.
73  */
74 void rtl88eu_mon_recv_hook(struct net_device *dev, struct recv_frame *frame)
75 {
76         struct rx_pkt_attrib *attr;
77         int iv_len, icv_len;
78         int data_len;
79         u8 *data;
80
81         if (!dev || !frame)
82                 return;
83         if (!netif_running(dev))
84                 return;
85
86         attr = &frame->attrib;
87         data = frame->pkt->data;
88         data_len = frame->pkt->len;
89
90         /* Broadcast and multicast frames don't have attr->{iv,icv}_len set */
91         SET_ICE_IV_LEN(iv_len, icv_len, attr->encrypt);
92
93         if (attr->bdecrypted)
94                 mon_recv_decrypted(dev, data, data_len, iv_len, icv_len);
95         else
96                 mon_recv_encrypted(dev, data, data_len);
97 }
98
99 /**
100  * rtl88eu_mon_xmit_hook() - forward trasmitted frame to the monitor interface
101  *
102  * Assumes that:
103  * - frame header contains an IV and frame->attrib.iv_len is set accordingly,
104  * - data is not encrypted and ICV/MIC has not been appended yet.
105  */
106 void rtl88eu_mon_xmit_hook(struct net_device *dev, struct xmit_frame *frame,
107                            uint frag_len)
108 {
109         struct pkt_attrib *attr;
110         u8 *data;
111         int i, offset;
112
113         if (!dev || !frame)
114                 return;
115         if (!netif_running(dev))
116                 return;
117
118         attr = &frame->attrib;
119
120         offset = TXDESC_SIZE + frame->pkt_offset * PACKET_OFFSET_SZ;
121         data = frame->buf_addr + offset;
122
123         for (i = 0; i < attr->nr_frags - 1; i++) {
124                 mon_recv_decrypted(dev, data, frag_len, attr->iv_len, 0);
125                 data += frag_len;
126                 data = (u8 *)round_up((size_t)data, 4);
127         }
128         /* Last fragment has different length */
129         mon_recv_decrypted(dev, data, attr->last_txcmdsz, attr->iv_len, 0);
130 }
131
132 static netdev_tx_t mon_xmit(struct sk_buff *skb, struct net_device *dev)
133 {
134         dev_kfree_skb(skb);
135         return NETDEV_TX_OK;
136 }
137
138 static const struct net_device_ops mon_netdev_ops = {
139         .ndo_start_xmit         = mon_xmit,
140         .ndo_set_mac_address    = eth_mac_addr,
141         .ndo_validate_addr      = eth_validate_addr,
142 };
143
144 static void mon_setup(struct net_device *dev)
145 {
146         dev->netdev_ops = &mon_netdev_ops;
147         dev->needs_free_netdev = true;
148         ether_setup(dev);
149         dev->priv_flags |= IFF_NO_QUEUE;
150         dev->type = ARPHRD_IEEE80211;
151         /*
152          * Use a locally administered address (IEEE 802)
153          * XXX: Copied from mac80211_hwsim driver. Revisit.
154          */
155         eth_zero_addr(dev->dev_addr);
156         dev->dev_addr[0] = 0x12;
157 }
158
159 struct net_device *rtl88eu_mon_init(void)
160 {
161         struct net_device *dev;
162         int err;
163
164         dev = alloc_netdev(0, "mon%d", NET_NAME_UNKNOWN, mon_setup);
165         if (!dev)
166                 goto fail;
167
168         err = register_netdev(dev);
169         if (err < 0)
170                 goto fail_free_dev;
171
172         return dev;
173
174 fail_free_dev:
175         free_netdev(dev);
176 fail:
177         return NULL;
178 }
179
180 void rtl88eu_mon_deinit(struct net_device *dev)
181 {
182         if (!dev)
183                 return;
184
185         unregister_netdev(dev);
186 }