- Pull NetBSD David Young's bitops.h into sys/sys, nuke the local copies in
[dragonfly.git] / sys / dev / netif / rtw / rtwphy.c
1 /*
2  * Copyright (c) 2004, 2005 David Young.  All rights reserved.
3  *
4  * Programmed for NetBSD by David Young.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of David Young may not be used to endorse or promote
15  *    products derived from this software without specific prior
16  *    written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY David Young ``AS IS'' AND ANY
19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
21  * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL David
22  * Young BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
24  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
29  * OF SUCH DAMAGE.
30  *
31  * $NetBSD: rtwphy.c,v 1.9 2006/03/08 00:24:06 dyoung Exp $
32  * $DragonFly: src/sys/dev/netif/rtw/rtwphy.c,v 1.4 2007/10/14 04:15:17 sephe Exp $
33  */
34
35 /*
36  * Control the Philips SA2400 RF front-end and the baseband processor
37  * built into the Realtek RTL8180.
38  */
39
40 #include <sys/param.h>
41 #include <sys/bitops.h>
42 #include <sys/bus.h>
43 #include <sys/socket.h>
44
45 #include <net/if.h>
46 #include <net/if_arp.h>
47 #include <net/if_media.h>
48
49 #include <netproto/802_11/ieee80211_var.h>
50 #include <netproto/802_11/ieee80211_radiotap.h>
51
52 #include <dev/netif/rtw/rtwreg.h>
53 #include <dev/netif/rtw/max2820reg.h>
54 #include <dev/netif/rtw/sa2400reg.h>
55 #include <dev/netif/rtw/rtwvar.h>
56 #include <dev/netif/rtw/rtwphyio.h>
57 #include <dev/netif/rtw/rtwphy.h>
58
59 static int      rtw_max2820_pwrstate(struct rtw_rf *, enum rtw_pwrstate);
60 static int      rtw_sa2400_pwrstate(struct rtw_rf *, enum rtw_pwrstate);
61
62 #define GCT_WRITE(__gr, __addr, __val, __label)                 \
63 do {                                                            \
64         if (rtw_rfbus_write(&(__gr)->gr_bus, RTW_RFCHIPID_GCT,  \
65             (__addr), (__val)) == -1)                           \
66                 goto __label;                                   \
67 } while(0)
68
69 static int
70 rtw_bbp_preinit(struct rtw_regs *regs, u_int antatten0, int dflantb, u_int freq)
71 {
72         u_int antatten = antatten0;
73
74         if (dflantb)
75                 antatten |= RTW_BBP_ANTATTEN_DFLANTB;
76         if (freq == 2484) /* channel 14 */
77                 antatten |= RTW_BBP_ANTATTEN_CHAN14;
78         return rtw_bbp_write(regs, RTW_BBP_ANTATTEN, antatten);
79 }
80
81 static int
82 rtw_bbp_init(struct rtw_regs *regs, struct rtw_bbpset *bb, int antdiv,
83              int dflantb, uint8_t cs_threshold, u_int freq)
84 {
85         int rc;
86         uint32_t sys2, sys3;
87
88         sys2 = bb->bb_sys2;
89         if (antdiv)
90                 sys2 |= RTW_BBP_SYS2_ANTDIV;
91         sys3 = bb->bb_sys3 |
92                __SHIFTIN(cs_threshold, RTW_BBP_SYS3_CSTHRESH_MASK);
93
94 #define RTW_BBP_WRITE_OR_RETURN(reg, val) \
95         if ((rc = rtw_bbp_write(regs, reg, val)) != 0) \
96                 return rc;
97
98         RTW_BBP_WRITE_OR_RETURN(RTW_BBP_SYS1,           bb->bb_sys1);
99         RTW_BBP_WRITE_OR_RETURN(RTW_BBP_TXAGC,          bb->bb_txagc);
100         RTW_BBP_WRITE_OR_RETURN(RTW_BBP_LNADET,         bb->bb_lnadet);
101         RTW_BBP_WRITE_OR_RETURN(RTW_BBP_IFAGCINI,       bb->bb_ifagcini);
102         RTW_BBP_WRITE_OR_RETURN(RTW_BBP_IFAGCLIMIT,     bb->bb_ifagclimit);
103         RTW_BBP_WRITE_OR_RETURN(RTW_BBP_IFAGCDET,       bb->bb_ifagcdet);
104
105         if ((rc = rtw_bbp_preinit(regs, bb->bb_antatten, dflantb, freq)) != 0)
106                 return rc;
107
108         RTW_BBP_WRITE_OR_RETURN(RTW_BBP_TRL,            bb->bb_trl);
109         RTW_BBP_WRITE_OR_RETURN(RTW_BBP_SYS2,           sys2);
110         RTW_BBP_WRITE_OR_RETURN(RTW_BBP_SYS3,           sys3);
111         RTW_BBP_WRITE_OR_RETURN(RTW_BBP_CHESTLIM,       bb->bb_chestlim);
112         RTW_BBP_WRITE_OR_RETURN(RTW_BBP_CHSQLIM,        bb->bb_chsqlim);
113         return 0;
114 }
115
116 static int
117 rtw_sa2400_txpower(struct rtw_rf *rf, uint8_t opaque_txpower)
118 {
119         struct rtw_sa2400 *sa = (struct rtw_sa2400 *)rf;
120         struct rtw_rfbus *bus = &sa->sa_bus;
121
122         return rtw_rfbus_write(bus, RTW_RFCHIPID_PHILIPS, SA2400_TX,
123                                opaque_txpower);
124 }
125
126 /* make sure we're using the same settings as the reference driver */
127 static void
128 verify_syna(u_int freq, uint32_t val)
129 {
130         uint32_t expected_val = ~val;
131
132         switch (freq) {
133         case 2412:
134                 expected_val = 0x0000096c; /* ch 1 */
135                 break;
136         case 2417:
137                 expected_val = 0x00080970; /* ch 2 */
138                 break;
139         case 2422:
140                 expected_val = 0x00100974; /* ch 3 */
141                 break;
142         case 2427:
143                 expected_val = 0x00180978; /* ch 4 */
144                 break;
145         case 2432:
146                 expected_val = 0x00000980; /* ch 5 */
147                 break;
148         case 2437:
149                 expected_val = 0x00080984; /* ch 6 */
150                 break;
151         case 2442:
152                 expected_val = 0x00100988; /* ch 7 */
153                 break;
154         case 2447:
155                 expected_val = 0x0018098c; /* ch 8 */
156                 break;
157         case 2452:
158                 expected_val = 0x00000994; /* ch 9 */
159                 break;
160         case 2457:
161                 expected_val = 0x00080998; /* ch 10 */
162                 break;
163         case 2462:
164                 expected_val = 0x0010099c; /* ch 11 */
165                 break;
166         case 2467:
167                 expected_val = 0x001809a0; /* ch 12 */
168                 break;
169         case 2472:
170                 expected_val = 0x000009a8; /* ch 13 */
171                 break;
172         case 2484:
173                 expected_val = 0x000009b4; /* ch 14 */
174                 break;
175         }
176         KKASSERT(val == expected_val);
177 }
178
179 /* freq is in MHz */
180 static int
181 rtw_sa2400_tune(struct rtw_rf *rf, u_int freq)
182 {
183         struct rtw_sa2400 *sa = (struct rtw_sa2400 *)rf;
184         struct rtw_rfbus *bus = &sa->sa_bus;
185         int rc;
186         uint32_t syna, synb, sync;
187         int n, nf;
188
189         /*
190          * XO = 44MHz, R = 11, hence N is in units of XO / R = 4MHz.
191          *
192          * The channel spacing (5MHz) is not divisible by 4MHz, so
193          * we set the fractional part of N to compensate.
194          */
195         n = freq / 4;
196         nf = (freq % 4) * 2;
197
198         syna = __SHIFTIN(nf, SA2400_SYNA_NF_MASK) |
199                __SHIFTIN(n, SA2400_SYNA_N_MASK);
200         verify_syna(freq, syna);
201
202         /*
203          * Divide the 44MHz crystal down to 4MHz. Set the fractional
204          * compensation charge pump value to agree with the fractional
205          * modulus.
206          */
207         synb = __SHIFTIN(11, SA2400_SYNB_R_MASK) | SA2400_SYNB_L_NORMAL |
208                SA2400_SYNB_ON | SA2400_SYNB_ONE |
209                __SHIFTIN(80, SA2400_SYNB_FC_MASK); /* agrees w/ SA2400_SYNA_FM = 0 */
210
211         sync = SA2400_SYNC_CP_NORMAL;
212
213         rc = rtw_rfbus_write(bus, RTW_RFCHIPID_PHILIPS, SA2400_SYNA, syna);
214         if (rc != 0)
215                 return rc;
216
217         rc = rtw_rfbus_write(bus, RTW_RFCHIPID_PHILIPS, SA2400_SYNB, synb);
218         if (rc != 0)
219                 return rc;
220
221         rc = rtw_rfbus_write(bus, RTW_RFCHIPID_PHILIPS, SA2400_SYNC, sync);
222         if (rc != 0)
223                 return rc;
224
225         return rtw_rfbus_write(bus, RTW_RFCHIPID_PHILIPS, SA2400_SYND, 0x0);
226 }
227
228 static int
229 rtw_sa2400_pwrstate(struct rtw_rf *rf, enum rtw_pwrstate power)
230 {
231         struct rtw_sa2400 *sa = (struct rtw_sa2400 *)rf;
232         struct rtw_rfbus *bus = &sa->sa_bus;
233         uint32_t opmode;
234
235         opmode = SA2400_OPMODE_DEFAULTS;
236         switch (power) {
237         case RTW_ON:
238                 opmode |= SA2400_OPMODE_MODE_TXRX;
239                 break;
240         case RTW_SLEEP:
241                 opmode |= SA2400_OPMODE_MODE_WAIT;
242                 break;
243         case RTW_OFF:
244                 opmode |= SA2400_OPMODE_MODE_SLEEP;
245                 break;
246         }
247
248         if (sa->sa_digphy)
249                 opmode |= SA2400_OPMODE_DIGIN;
250
251         return rtw_rfbus_write(bus, RTW_RFCHIPID_PHILIPS, SA2400_OPMODE,
252                                opmode);
253 }
254
255 static int
256 rtw_sa2400_manrx_init(struct rtw_sa2400 *sa)
257 {
258         uint32_t manrx;
259
260         /*
261          * XXX we are not supposed to be in RXMGC mode when we do this?
262          */
263         manrx = SA2400_MANRX_AHSN;
264         manrx |= SA2400_MANRX_TEN;
265         manrx |= __SHIFTIN(1023, SA2400_MANRX_RXGAIN_MASK);
266
267         return rtw_rfbus_write(&sa->sa_bus, RTW_RFCHIPID_PHILIPS, SA2400_MANRX,
268                                manrx);
269 }
270
271 static int
272 rtw_sa2400_vcocal_start(struct rtw_sa2400 *sa, int start)
273 {
274         uint32_t opmode;
275
276         opmode = SA2400_OPMODE_DEFAULTS;
277         if (start)
278                 opmode |= SA2400_OPMODE_MODE_VCOCALIB;
279         else
280                 opmode |= SA2400_OPMODE_MODE_SLEEP;
281
282         if (sa->sa_digphy)
283                 opmode |= SA2400_OPMODE_DIGIN;
284
285         return rtw_rfbus_write(&sa->sa_bus, RTW_RFCHIPID_PHILIPS, SA2400_OPMODE,
286                                opmode);
287 }
288
289 static int
290 rtw_sa2400_vco_calibration(struct rtw_sa2400 *sa)
291 {
292         int rc;
293
294         /* calibrate VCO */
295         if ((rc = rtw_sa2400_vcocal_start(sa, 1)) != 0)
296                 return rc;
297         DELAY(2200);    /* 2.2 milliseconds */
298         /* XXX superfluous: SA2400 automatically entered SLEEP mode. */
299         return rtw_sa2400_vcocal_start(sa, 0);
300 }
301
302 static int
303 rtw_sa2400_filter_calibration(struct rtw_sa2400 *sa)
304 {
305         uint32_t opmode;
306
307         opmode = SA2400_OPMODE_DEFAULTS | SA2400_OPMODE_MODE_FCALIB;
308         if (sa->sa_digphy)
309                 opmode |= SA2400_OPMODE_DIGIN;
310
311         return rtw_rfbus_write(&sa->sa_bus, RTW_RFCHIPID_PHILIPS, SA2400_OPMODE,
312                                opmode);
313 }
314
315 static int
316 rtw_sa2400_dc_calibration(struct rtw_sa2400 *sa)
317 {
318         struct rtw_rf *rf = &sa->sa_rf;
319         int rc;
320         uint32_t dccal;
321
322         rf->rf_continuous_tx_cb(rf->rf_continuous_tx_arg, 1);
323
324         dccal = SA2400_OPMODE_DEFAULTS | SA2400_OPMODE_MODE_TXRX;
325
326         rc = rtw_rfbus_write(&sa->sa_bus, RTW_RFCHIPID_PHILIPS, SA2400_OPMODE,
327                              dccal);
328         if (rc != 0)
329                 return rc;
330
331         /*
332          * DCALIB after being in Tx mode for 5 microseconds
333          */
334         DELAY(5);
335
336         dccal &= ~SA2400_OPMODE_MODE_MASK;
337         dccal |= SA2400_OPMODE_MODE_DCALIB;
338
339         rc = rtw_rfbus_write(&sa->sa_bus, RTW_RFCHIPID_PHILIPS, SA2400_OPMODE,
340                              dccal);
341         if (rc != 0)
342                 return rc;
343
344         DELAY(20);      /* calibration takes at most 20 microseconds */
345
346         rf->rf_continuous_tx_cb(rf->rf_continuous_tx_arg, 0);
347         return 0;
348 }
349
350 static int
351 rtw_sa2400_agc_init(struct rtw_sa2400 *sa)
352 {
353         uint32_t agc;
354
355         agc = __SHIFTIN(25, SA2400_AGC_MAXGAIN_MASK);
356         agc |= __SHIFTIN(7, SA2400_AGC_BBPDELAY_MASK);
357         agc |= __SHIFTIN(15, SA2400_AGC_LNADELAY_MASK);
358         agc |= __SHIFTIN(27, SA2400_AGC_RXONDELAY_MASK);
359
360         return rtw_rfbus_write(&sa->sa_bus, RTW_RFCHIPID_PHILIPS, SA2400_AGC,
361                                agc);
362 }
363
364 static void
365 rtw_sa2400_destroy(struct rtw_rf *rf)
366 {
367         struct rtw_sa2400 *sa = (struct rtw_sa2400 *)rf;
368
369         memset(sa, 0, sizeof(*sa));
370         kfree(sa, M_DEVBUF);
371 }
372
373 static int
374 rtw_sa2400_calibrate(struct rtw_rf *rf, u_int freq)
375 {
376         struct rtw_sa2400 *sa = (struct rtw_sa2400 *)rf;
377         int i, rc;
378
379         /* XXX reference driver calibrates VCO twice. Is it a bug? */
380         for (i = 0; i < 2; i++) {
381                 if ((rc = rtw_sa2400_vco_calibration(sa)) != 0)
382                         return rc;
383         }
384         /* VCO calibration erases synthesizer registers, so re-tune */
385         if ((rc = rtw_sa2400_tune(rf, freq)) != 0)
386                 return rc;
387         if ((rc = rtw_sa2400_filter_calibration(sa)) != 0)
388                 return rc;
389         /* analog PHY needs DC calibration */
390         if (!sa->sa_digphy)
391                 return rtw_sa2400_dc_calibration(sa);
392         return 0;
393 }
394
395 static int
396 rtw_sa2400_init(struct rtw_rf *rf, u_int freq, uint8_t opaque_txpower,
397                 enum rtw_pwrstate power)
398 {
399         struct rtw_sa2400 *sa = (struct rtw_sa2400 *)rf;
400         int rc;
401
402         if ((rc = rtw_sa2400_txpower(rf, opaque_txpower)) != 0)
403                 return rc;
404
405         /* skip configuration if it's time to sleep or to power-down. */
406         if (power == RTW_SLEEP || power == RTW_OFF)
407                 return rtw_sa2400_pwrstate(rf, power);
408
409         /* go to sleep for configuration */
410         if ((rc = rtw_sa2400_pwrstate(rf, RTW_SLEEP)) != 0)
411                 return rc;
412
413         if ((rc = rtw_sa2400_tune(rf, freq)) != 0)
414                 return rc;
415         if ((rc = rtw_sa2400_agc_init(sa)) != 0)
416                 return rc;
417         if ((rc = rtw_sa2400_manrx_init(sa)) != 0)
418                 return rc;
419         if ((rc = rtw_sa2400_calibrate(rf, freq)) != 0)
420                 return rc;
421
422         /* enter Tx/Rx mode */
423         return rtw_sa2400_pwrstate(rf, power);
424 }
425
426 struct rtw_rf *
427 rtw_sa2400_create(struct rtw_regs *regs, rtw_rf_write_t rf_write, int digphy)
428 {
429         struct rtw_sa2400 *sa;
430         struct rtw_rfbus *bus;
431         struct rtw_rf *rf;
432         struct rtw_bbpset *bb;
433
434         sa = kmalloc(sizeof(*sa), M_DEVBUF, M_WAITOK | M_ZERO);
435
436         sa->sa_digphy = digphy;
437
438         rf = &sa->sa_rf;
439         bus = &sa->sa_bus;
440
441         rf->rf_init = rtw_sa2400_init;
442         rf->rf_destroy = rtw_sa2400_destroy;
443         rf->rf_txpower = rtw_sa2400_txpower;
444         rf->rf_tune = rtw_sa2400_tune;
445         rf->rf_pwrstate = rtw_sa2400_pwrstate;
446         bb = &rf->rf_bbpset;
447
448         /* XXX magic */
449         bb->bb_antatten = RTW_BBP_ANTATTEN_PHILIPS_MAGIC;
450         bb->bb_chestlim =       0x00;
451         bb->bb_chsqlim =        0xa0;
452         bb->bb_ifagcdet =       0x64;
453         bb->bb_ifagcini =       0x90;
454         bb->bb_ifagclimit =     0x1a;
455         bb->bb_lnadet =         0xe0;
456         bb->bb_sys1 =           0x98;
457         bb->bb_sys2 =           0x47;
458         bb->bb_sys3 =           0x90;
459         bb->bb_trl =            0x88;
460         bb->bb_txagc =          0x38;
461
462         bus->b_regs = regs;
463         bus->b_write = rf_write;
464
465         return &sa->sa_rf;
466 }
467
468 static int
469 rtw_grf5101_txpower(struct rtw_rf *rf, uint8_t opaque_txpower)
470 {
471         struct rtw_grf5101 *gr = (struct rtw_grf5101 *)rf;
472
473         GCT_WRITE(gr, 0x15, 0, err);
474         GCT_WRITE(gr, 0x06, opaque_txpower, err);
475         GCT_WRITE(gr, 0x15, 0x10, err);
476         GCT_WRITE(gr, 0x15, 0x00, err);
477         return 0;
478 err:
479         return -1;
480 }
481
482 static int
483 rtw_grf5101_pwrstate(struct rtw_rf *rf, enum rtw_pwrstate power)
484 {
485         struct rtw_grf5101 *gr = (struct rtw_grf5101 *)rf;
486
487         switch (power) {
488         case RTW_OFF:
489         case RTW_SLEEP:
490                 GCT_WRITE(gr, 0x07, 0x0000, err);
491                 GCT_WRITE(gr, 0x1f, 0x0045, err);
492                 GCT_WRITE(gr, 0x1f, 0x0005, err);
493                 GCT_WRITE(gr, 0x00, 0x08e4, err);
494         default:
495                 break;
496         case RTW_ON:
497                 GCT_WRITE(gr, 0x1f, 0x0001, err);
498                 DELAY(10);
499                 GCT_WRITE(gr, 0x1f, 0x0001, err);
500                 DELAY(10);
501                 GCT_WRITE(gr, 0x1f, 0x0041, err);
502                 DELAY(10);
503                 GCT_WRITE(gr, 0x1f, 0x0061, err);
504                 DELAY(10);
505                 GCT_WRITE(gr, 0x00, 0x0ae4, err);
506                 DELAY(10);
507                 GCT_WRITE(gr, 0x07, 0x1000, err);
508                 DELAY(100);
509                 break;
510         }
511
512         return 0;
513 err:
514         return -1;
515 }
516
517 static int
518 rtw_grf5101_tune(struct rtw_rf *rf, u_int freq)
519 {
520         int channel;
521         struct rtw_grf5101 *gr = (struct rtw_grf5101 *)rf;
522
523         if (freq == 2484) {
524                 channel = 14;
525         } else if ((channel = (freq - 2412) / 5 + 1) < 1 || channel > 13) {
526                 RTW_DPRINTF(RTW_DEBUG_PHY,
527                     ("%s: invalid channel %d (freq %d)\n", __func__, channel,
528                      freq));
529                 return -1;
530         }
531
532         GCT_WRITE(gr, 0x07, 0, err);
533         GCT_WRITE(gr, 0x0b, channel - 1, err);
534         GCT_WRITE(gr, 0x07, 0x1000, err);
535         return 0;
536 err:
537         return -1;
538 }
539
540 static int
541 rtw_grf5101_init(struct rtw_rf *rf, u_int freq, uint8_t opaque_txpower,
542                  enum rtw_pwrstate power)
543 {
544         int rc;
545         struct rtw_grf5101 *gr = (struct rtw_grf5101 *)rf;
546
547         /*
548          * These values have been derived from the rtl8180-sa2400
549          * Linux driver.  It is unknown what they all do, GCT refuse
550          * to release any documentation so these are more than
551          * likely sub optimal settings
552          */
553
554         GCT_WRITE(gr, 0x01, 0x1a23, err);
555         GCT_WRITE(gr, 0x02, 0x4971, err);
556         GCT_WRITE(gr, 0x03, 0x41de, err);
557         GCT_WRITE(gr, 0x04, 0x2d80, err);
558
559         GCT_WRITE(gr, 0x05, 0x61ff, err);
560
561         GCT_WRITE(gr, 0x06, 0x0, err);
562
563         GCT_WRITE(gr, 0x08, 0x7533, err);
564         GCT_WRITE(gr, 0x09, 0xc401, err);
565         GCT_WRITE(gr, 0x0a, 0x0, err);
566         GCT_WRITE(gr, 0x0c, 0x1c7, err);
567         GCT_WRITE(gr, 0x0d, 0x29d3, err);
568         GCT_WRITE(gr, 0x0e, 0x2e8, err);
569         GCT_WRITE(gr, 0x10, 0x192, err);
570         GCT_WRITE(gr, 0x11, 0x248, err);
571         GCT_WRITE(gr, 0x12, 0x0, err);
572         GCT_WRITE(gr, 0x13, 0x20c4, err);
573         GCT_WRITE(gr, 0x14, 0xf4fc, err);
574         GCT_WRITE(gr, 0x15, 0x0, err);
575         GCT_WRITE(gr, 0x16, 0x1500, err);
576
577         if ((rc = rtw_grf5101_txpower(rf, opaque_txpower)) != 0)
578                 return rc;
579
580         if ((rc = rtw_grf5101_tune(rf, freq)) != 0)
581                 return rc;
582
583         return 0;
584 err:
585         return -1;
586 }
587
588 static void
589 rtw_grf5101_destroy(struct rtw_rf *rf)
590 {
591         struct rtw_grf5101 *gr = (struct rtw_grf5101 *)rf;
592
593         memset(gr, 0, sizeof(*gr));
594         kfree(gr, M_DEVBUF);
595 }
596
597 struct rtw_rf *
598 rtw_grf5101_create(struct rtw_regs *regs, rtw_rf_write_t rf_write, int digphy)
599 {
600         struct rtw_grf5101 *gr;
601         struct rtw_rfbus *bus;
602         struct rtw_rf *rf;
603         struct rtw_bbpset *bb;
604
605         gr = kmalloc(sizeof(*gr), M_DEVBUF, M_WAITOK | M_ZERO);
606
607         rf = &gr->gr_rf;
608         bus = &gr->gr_bus;
609
610         rf->rf_init = rtw_grf5101_init;
611         rf->rf_destroy = rtw_grf5101_destroy;
612         rf->rf_txpower = rtw_grf5101_txpower;
613         rf->rf_tune = rtw_grf5101_tune;
614         rf->rf_pwrstate = rtw_grf5101_pwrstate;
615         bb = &rf->rf_bbpset;
616
617         /* XXX magic */
618         bb->bb_antatten = RTW_BBP_ANTATTEN_GCT_MAGIC;
619         bb->bb_chestlim =       0x00;
620         bb->bb_chsqlim =        0xa0;
621         bb->bb_ifagcdet =       0x64;
622         bb->bb_ifagcini =       0x90;
623         bb->bb_ifagclimit =     0x1e;
624         bb->bb_lnadet =         0xc0;
625         bb->bb_sys1 =           0xa8;
626         bb->bb_sys2 =           0x47;
627         bb->bb_sys3 =           0x9b;
628         bb->bb_trl =            0x88;
629         bb->bb_txagc =          0x08;
630
631         bus->b_regs = regs;
632         bus->b_write = rf_write;
633
634         return &gr->gr_rf;
635 }
636
637 /* freq is in MHz */
638 static int
639 rtw_max2820_tune(struct rtw_rf *rf, u_int freq)
640 {
641         struct rtw_max2820 *mx = (struct rtw_max2820 *)rf;
642         struct rtw_rfbus *bus = &mx->mx_bus;
643
644         if (freq < 2400 || freq > 2499)
645                 return -1;
646
647         return rtw_rfbus_write(bus, RTW_RFCHIPID_MAXIM, MAX2820_CHANNEL,
648                                __SHIFTIN(freq - 2400, MAX2820_CHANNEL_CF_MASK));
649 }
650
651 static void
652 rtw_max2820_destroy(struct rtw_rf *rf)
653 {
654         struct rtw_max2820 *mx = (struct rtw_max2820 *)rf;
655
656         memset(mx, 0, sizeof(*mx));
657         kfree(mx, M_DEVBUF);
658 }
659
660 static int
661 rtw_max2820_init(struct rtw_rf *rf, u_int freq, uint8_t opaque_txpower,
662                  enum rtw_pwrstate power)
663 {
664         struct rtw_max2820 *mx = (struct rtw_max2820 *)rf;
665         struct rtw_rfbus *bus = &mx->mx_bus;
666         int rc;
667
668         rc = rtw_rfbus_write(bus, RTW_RFCHIPID_MAXIM, MAX2820_TEST,
669                              MAX2820_TEST_DEFAULT);
670         if (rc != 0)
671                 return rc;
672
673         rc = rtw_rfbus_write(bus, RTW_RFCHIPID_MAXIM, MAX2820_ENABLE,
674                              MAX2820_ENABLE_DEFAULT);
675         if (rc != 0)
676                 return rc;
677
678         /* skip configuration if it's time to sleep or to power-down. */
679         if ((rc = rtw_max2820_pwrstate(rf, power)) != 0)
680                 return rc;
681         else if (power == RTW_OFF || power == RTW_SLEEP)
682                 return 0;
683
684         rc = rtw_rfbus_write(bus, RTW_RFCHIPID_MAXIM, MAX2820_SYNTH,
685                              MAX2820_SYNTH_R_44MHZ);
686         if (rc != 0)
687                 return rc;
688
689         if ((rc = rtw_max2820_tune(rf, freq)) != 0)
690                 return rc;
691
692         /*
693          * XXX The MAX2820 datasheet indicates that 1C and 2C should not
694          * be changed from 7, however, the reference driver sets them
695          * to 4 and 1, respectively.
696          */
697         rc = rtw_rfbus_write(bus, RTW_RFCHIPID_MAXIM, MAX2820_RECEIVE,
698                              MAX2820_RECEIVE_DL_DEFAULT |
699                              __SHIFTIN(4, MAX2820A_RECEIVE_1C_MASK) |
700                              __SHIFTIN(1, MAX2820A_RECEIVE_2C_MASK));
701         if (rc != 0)
702                 return rc;
703
704         return rtw_rfbus_write(bus, RTW_RFCHIPID_MAXIM, MAX2820_TRANSMIT,
705                                MAX2820_TRANSMIT_PA_DEFAULT);
706 }
707
708 static int
709 rtw_max2820_txpower(struct rtw_rf *rf, uint8_t opaque_txpower)
710 {
711         /* TBD */
712         return 0;
713 }
714
715 static int
716 rtw_max2820_pwrstate(struct rtw_rf *rf, enum rtw_pwrstate power)
717 {
718         uint32_t enable;
719         struct rtw_max2820 *mx;
720         struct rtw_rfbus *bus;
721
722         mx = (struct rtw_max2820 *)rf;
723         bus = &mx->mx_bus;
724
725         switch (power) {
726         case RTW_OFF:
727         case RTW_SLEEP:
728         default:
729                 enable = 0x0;
730                 break;
731         case RTW_ON:
732                 enable = MAX2820_ENABLE_DEFAULT;
733                 break;
734         }
735         return rtw_rfbus_write(bus, RTW_RFCHIPID_MAXIM, MAX2820_ENABLE, enable);
736 }
737
738 struct rtw_rf *
739 rtw_max2820_create(struct rtw_regs *regs, rtw_rf_write_t rf_write, int is_a)
740 {
741         struct rtw_max2820 *mx;
742         struct rtw_rfbus *bus;
743         struct rtw_rf *rf;
744         struct rtw_bbpset *bb;
745
746         mx = kmalloc(sizeof(*mx), M_DEVBUF, M_WAITOK | M_ZERO);
747
748         mx->mx_is_a = is_a;
749
750         rf = &mx->mx_rf;
751         bus = &mx->mx_bus;
752
753         rf->rf_init = rtw_max2820_init;
754         rf->rf_destroy = rtw_max2820_destroy;
755         rf->rf_txpower = rtw_max2820_txpower;
756         rf->rf_tune = rtw_max2820_tune;
757         rf->rf_pwrstate = rtw_max2820_pwrstate;
758         bb = &rf->rf_bbpset;
759
760         /* XXX magic */
761         bb->bb_antatten = RTW_BBP_ANTATTEN_MAXIM_MAGIC;
762         bb->bb_chestlim =       0;
763         bb->bb_chsqlim =        159;
764         bb->bb_ifagcdet =       100;
765         bb->bb_ifagcini =       144;
766         bb->bb_ifagclimit =     26;
767         bb->bb_lnadet =         248;
768         bb->bb_sys1 =           136;
769         bb->bb_sys2 =           71;
770         bb->bb_sys3 =           155;
771         bb->bb_trl =            136;
772         bb->bb_txagc =          8;
773
774         bus->b_regs = regs;
775         bus->b_write = rf_write;
776
777         return &mx->mx_rf;
778 }
779
780 /* freq is in MHz */
781 int
782 rtw_phy_init(struct rtw_regs *regs, struct rtw_rf *rf, uint8_t opaque_txpower,
783              uint8_t cs_threshold, u_int freq, int antdiv, int dflantb,
784              enum rtw_pwrstate power)
785 {
786         int rc;
787         RTW_DPRINTF(RTW_DEBUG_PHY,
788             ("%s: txpower %u csthresh %u freq %u antdiv %u dflantb %u "
789              "pwrstate %s\n", __func__, opaque_txpower, cs_threshold, freq,
790              antdiv, dflantb, rtw_pwrstate_string(power)));
791
792         /* XXX is this really necessary? */
793         if ((rc = rtw_rf_txpower(rf, opaque_txpower)) != 0)
794                 return rc;
795
796         rc = rtw_bbp_preinit(regs, rf->rf_bbpset.bb_antatten, dflantb, freq);
797         if (rc != 0)
798                 return rc;
799
800         if ((rc = rtw_rf_tune(rf, freq)) != 0)
801                 return rc;
802
803         /* initialize RF  */
804         if ((rc = rtw_rf_init(rf, freq, opaque_txpower, power)) != 0)
805                 return rc;
806 #if 0   /* what is this redundant tx power setting here for? */
807         if ((rc = rtw_rf_txpower(rf, opaque_txpower)) != 0)
808                 return rc;
809 #endif
810         return rtw_bbp_init(regs, &rf->rf_bbpset, antdiv, dflantb, cs_threshold,                            freq);
811 }