The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/ic/rtwphy.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 572f39dcc7fc0c1e43bed31d1819ca2d


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.