]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/rtwn/rtl8188e/r88e_rx.c
Update compiler-rt to release_39 branch r288513. Since this contains a
[FreeBSD/FreeBSD.git] / sys / dev / rtwn / rtl8188e / r88e_rx.c
1 /*      $OpenBSD: if_urtwn.c,v 1.16 2011/02/10 17:26:40 jakemsr Exp $   */
2
3 /*-
4  * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
5  * Copyright (c) 2014 Kevin Lo <kevlo@FreeBSD.org>
6  * Copyright (c) 2015-2016 Andriy Voskoboinyk <avos@FreeBSD.org>
7  *
8  * Permission to use, copy, modify, and distribute this software for any
9  * purpose with or without fee is hereby granted, provided that the above
10  * copyright notice and this permission notice appear in all copies.
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19  */
20
21 #include <sys/cdefs.h>
22 __FBSDID("$FreeBSD$");
23
24 #include "opt_wlan.h"
25
26 #include <sys/param.h>
27 #include <sys/lock.h>
28 #include <sys/mutex.h>
29 #include <sys/mbuf.h>
30 #include <sys/kernel.h>
31 #include <sys/socket.h>
32 #include <sys/systm.h>
33 #include <sys/malloc.h>
34 #include <sys/queue.h>
35 #include <sys/taskqueue.h>
36 #include <sys/bus.h>
37 #include <sys/endian.h>
38 #include <sys/linker.h>
39
40 #include <net/if.h>
41 #include <net/ethernet.h>
42 #include <net/if_media.h>
43
44 #include <net80211/ieee80211_var.h>
45 #include <net80211/ieee80211_radiotap.h>
46 #include <net80211/ieee80211_ratectl.h>
47
48 #include <dev/rtwn/if_rtwnreg.h>
49 #include <dev/rtwn/if_rtwnvar.h>
50
51 #include <dev/rtwn/if_rtwn_debug.h>
52 #include <dev/rtwn/if_rtwn_ridx.h>
53
54 #include <dev/rtwn/rtl8188e/r88e.h>
55 #include <dev/rtwn/rtl8188e/r88e_rx_desc.h>
56
57
58 void
59 r88e_ratectl_tx_complete(struct rtwn_softc *sc, uint8_t *buf, int len)
60 {
61 #if __FreeBSD_version >= 1200012
62         struct ieee80211_ratectl_tx_status txs;
63 #endif
64         struct r88e_tx_rpt_ccx *rpt;
65         struct ieee80211_node *ni;
66         uint8_t macid;
67         int ntries;
68
69         /* Skip Rx descriptor. */
70         buf += sizeof(struct r92c_rx_stat);
71         len -= sizeof(struct r92c_rx_stat);
72
73         rpt = (struct r88e_tx_rpt_ccx *)buf;
74         if (len != sizeof(*rpt)) {
75                 RTWN_DPRINTF(sc, RTWN_DEBUG_INTR,
76                     "%s: wrong report size (%d, must be %zu)\n",
77                     __func__, len, sizeof(*rpt));
78                 return;
79         }
80
81         RTWN_DPRINTF(sc, RTWN_DEBUG_INTR,
82             "%s: ccx report dump: 0: %02X, 1: %02X, 2: %02X, queue time: "
83             "low %02X, high %02X, final ridx: %02X, 6: %02X, 7: %02X\n",
84             __func__, rpt->rptb0, rpt->rptb1, rpt->rptb2, rpt->queue_time_low,
85             rpt->queue_time_high, rpt->final_rate, rpt->rptb6, rpt->rptb7);
86
87         macid = MS(rpt->rptb1, R88E_RPTB1_MACID);
88         if (macid > sc->macid_limit) {
89                 device_printf(sc->sc_dev,
90                     "macid %u is too big; increase MACID_MAX limit\n",
91                     macid);
92                 return;
93         }
94
95         ntries = MS(rpt->rptb2, R88E_RPTB2_RETRY_CNT);
96
97         ni = sc->node_list[macid];
98         if (ni != NULL) {
99                 RTWN_DPRINTF(sc, RTWN_DEBUG_INTR, "%s: frame for macid %u was"
100                     "%s sent (%d retries)\n", __func__, macid,
101                     (rpt->rptb1 & R88E_RPTB1_PKT_OK) ? "" : " not",
102                     ntries);
103
104 #if __FreeBSD_version >= 1200012
105                 txs.flags = IEEE80211_RATECTL_STATUS_LONG_RETRY |
106                             IEEE80211_RATECTL_STATUS_FINAL_RATE;
107                 txs.long_retries = ntries;
108                 if (rpt->final_rate > RTWN_RIDX_OFDM54) {       /* MCS */
109                         txs.final_rate =
110                             (rpt->final_rate - 12) | IEEE80211_RATE_MCS;
111                 } else
112                         txs.final_rate = ridx2rate[rpt->final_rate];
113                 if (rpt->rptb1 & R88E_RPTB1_PKT_OK)
114                         txs.status = IEEE80211_RATECTL_TX_SUCCESS;
115                 else if (rpt->rptb2 & R88E_RPTB2_RETRY_OVER)
116                         txs.status = IEEE80211_RATECTL_TX_FAIL_LONG;
117                 else if (rpt->rptb2 & R88E_RPTB2_LIFE_EXPIRE)
118                         txs.status = IEEE80211_RATECTL_TX_FAIL_EXPIRED;
119                 else
120                         txs.status = IEEE80211_RATECTL_TX_FAIL_UNSPECIFIED;
121                 ieee80211_ratectl_tx_complete(ni, &txs);
122 #else
123                 struct ieee80211vap *vap = ni->ni_vap;
124                 if (rpt->rptb1 & R88E_RPTB1_PKT_OK) {
125                         ieee80211_ratectl_tx_complete(vap, ni,
126                             IEEE80211_RATECTL_TX_SUCCESS, &ntries, NULL);
127                 } else {
128                         ieee80211_ratectl_tx_complete(vap, ni,
129                             IEEE80211_RATECTL_TX_FAILURE, &ntries, NULL);
130                 }
131 #endif
132         } else {
133                 RTWN_DPRINTF(sc, RTWN_DEBUG_INTR, "%s: macid %u, ni is NULL\n",
134                     __func__, macid);
135         }
136 }
137
138 void
139 r88e_handle_c2h_report(struct rtwn_softc *sc, uint8_t *buf, int len)
140 {
141
142         /* Skip Rx descriptor. */
143         buf += sizeof(struct r92c_rx_stat);
144         len -= sizeof(struct r92c_rx_stat);
145
146         if (len != R88E_INTR_MSG_LEN) {
147                 RTWN_DPRINTF(sc, RTWN_DEBUG_INTR,
148                     "%s: wrong interrupt message size (%d, must be %d)\n",
149                     __func__, len, R88E_INTR_MSG_LEN);
150                 return;
151         }
152
153         /* XXX TODO */
154 }
155
156 int8_t
157 r88e_get_rssi_cck(struct rtwn_softc *sc, void *physt)
158 {
159         struct r88e_rx_phystat *phy = (struct r88e_rx_phystat *)physt;
160         int8_t lna_idx, vga_idx, rssi;
161
162         lna_idx = (phy->agc_rpt & 0xe0) >> 5;
163         vga_idx = (phy->agc_rpt & 0x1f);
164         rssi = 6 - 2 * vga_idx;
165
166         switch (lna_idx) {
167         case 7:
168                 if (vga_idx > 27)
169                         rssi = -100 + 6;
170                 else
171                         rssi += -100 + 2 * 27;
172                 break;
173         case 6:
174                 rssi += -48 + 2 * 2;
175                 break;
176         case 5:
177                 rssi += -42 + 2 * 7;
178                 break;
179         case 4:
180                 rssi += -36 + 2 * 7;
181                 break;
182         case 3:
183                 rssi += -24 + 2 * 7;
184                 break;
185         case 2:
186                 rssi += -6 + 2 * 5;
187                 if (sc->sc_flags & RTWN_FLAG_CCK_HIPWR)
188                         rssi -= 6;
189                 break;
190         case 1:
191                 rssi += 8;
192                 break;
193         case 0:
194                 rssi += 14;
195                 break;
196         }
197
198         return (rssi);
199 }
200
201 int8_t
202 r88e_get_rssi_ofdm(struct rtwn_softc *sc, void *physt)
203 {
204         struct r88e_rx_phystat *phy = (struct r88e_rx_phystat *)physt;
205         int rssi;
206
207         /* Get average RSSI. */
208         rssi = ((phy->sig_qual >> 1) & 0x7f) - 110;
209
210         return (rssi);
211 }