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/hfa/fore_init.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 /*
    2  *
    3  * ===================================
    4  * HARP  |  Host ATM Research Platform
    5  * ===================================
    6  *
    7  *
    8  * This Host ATM Research Platform ("HARP") file (the "Software") is
    9  * made available by Network Computing Services, Inc. ("NetworkCS")
   10  * "AS IS".  NetworkCS does not provide maintenance, improvements or
   11  * support of any kind.
   12  *
   13  * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
   14  * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
   15  * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
   16  * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
   17  * In no event shall NetworkCS be responsible for any damages, including
   18  * but not limited to consequential damages, arising from or relating to
   19  * any use of the Software or related support.
   20  *
   21  * Copyright 1994-1998 Network Computing Services, Inc.
   22  *
   23  * Copies of this Software may be made, however, the above copyright
   24  * notice must be reproduced on all copies.
   25  *
   26  *      @(#) $FreeBSD: releng/5.3/sys/dev/hfa/fore_init.c 126075 2004-02-21 19:08:23Z harti $
   27  *
   28  */
   29 
   30 /*
   31  * FORE Systems 200-Series Adapter Support
   32  * ---------------------------------------
   33  *
   34  * Cell Processor (CP) initialization routines
   35  *
   36  */
   37 
   38 #include <sys/param.h>
   39 #include <sys/kernel.h>
   40 #include <sys/systm.h>
   41 #include <sys/socket.h>
   42 #include <sys/socketvar.h>
   43 #include <sys/syslog.h>
   44 #include <vm/vm.h>
   45 #include <vm/pmap.h>
   46 #include <net/if.h>
   47 #include <netatm/port.h>
   48 #include <netatm/queue.h>
   49 #include <netatm/atm.h>
   50 #include <netatm/atm_sys.h>
   51 #include <netatm/atm_sap.h>
   52 #include <netatm/atm_cm.h>
   53 #include <netatm/atm_if.h>
   54 #include <netatm/atm_stack.h>
   55 #include <netatm/atm_pcb.h>
   56 #include <netatm/atm_var.h>
   57 #include <dev/pci/pcivar.h>
   58 #include <dev/hfa/fore.h>
   59 #include <dev/hfa/fore_aali.h>
   60 #include <dev/hfa/fore_slave.h>
   61 #include <dev/hfa/fore_stats.h>
   62 #include <dev/hfa/fore_var.h>
   63 #include <dev/hfa/fore_include.h>
   64 
   65 #ifndef lint
   66 __RCSID("@(#) $FreeBSD: releng/5.3/sys/dev/hfa/fore_init.c 126075 2004-02-21 19:08:23Z harti $");
   67 #endif
   68 
   69 
   70 /*
   71  * Local functions
   72  */
   73 static void     fore_get_prom(Fore_unit *);
   74 
   75 
   76 /*
   77  * Begin CP Initialization
   78  *
   79  * This function will poll for the successful downloading and starting of
   80  * the CP microcode program.  After the microcode is running, we will allocate
   81  * any needed kernel memory (must do it in non-interrupt mode), build the CP
   82  * queue configurations and issue an Initialize command to the CP.
   83  *
   84  * Arguments:
   85  *      fup             pointer to device unit structure
   86  *
   87  * Returns:
   88  *      none
   89  */
   90 void
   91 fore_initialize(fup)
   92         Fore_unit       *fup;
   93 {
   94         Aali            *aap;
   95         Init_parms      *inp;
   96         caddr_t         errmsg;
   97         u_long          vers;
   98         u_int c, wait;
   99 #define MAX_WAIT        100
  100 
  101         /*
  102          * Must wait until firmware has been downloaded and is running
  103          */
  104         if (CP_READ(fup->fu_mon->mon_bstat) != BOOT_RUNNING) {
  105 
  106                 /*
  107                  * Try again later
  108                  */
  109                 fup->fu_thandle = 
  110                         timeout((KTimeout_ret(*)(void *))fore_initialize,
  111                                 (void *)fup, hz);
  112                 return;
  113         } else
  114                 callout_handle_init(&fup->fu_thandle);
  115 
  116         /*
  117          * Allocate queues and whatever else is needed
  118          */
  119         if (fore_xmit_allocate(fup)) {
  120                 errmsg = "transmit queue allocation";
  121                 goto failed;
  122         }
  123         if (fore_recv_allocate(fup)) {
  124                 errmsg = "receive queue allocation";
  125                 goto failed;
  126         }
  127         if (fore_buf_allocate(fup)) {
  128                 errmsg = "buffer supply queue allocation";
  129                 goto failed;
  130         }
  131         if (fore_cmd_allocate(fup)) {
  132                 errmsg = "command queue allocation";
  133                 goto failed;
  134         }
  135 
  136         /*
  137          * CP microcode is downloaded - locate shared memory interface 
  138          */
  139         aap = (Aali *)(fup->fu_ram + CP_READ(fup->fu_mon->mon_appl));
  140         fup->fu_aali = aap;
  141 
  142         /*
  143          * Pick out any interesting info from the microcode
  144          */
  145         vers = CP_READ(aap->aali_ucode_ver);
  146         if (vers < FORE_MIN_UCODE) {
  147                 errmsg = "unsupported microcode version";
  148                 goto failed;
  149         }
  150         snprintf(fup->fu_config.ac_firm_vers,
  151             sizeof(fup->fu_config.ac_firm_vers), "%ld.%ld.%ld",
  152                 (vers >> 16) & 0xff, (vers >> 8) & 0xff, vers & 0xff);
  153 
  154         if (((vers >> 16) & 0xff) == 4)
  155                 fup->fu_ft4 = 1;
  156         else
  157                 fup->fu_ft4 = 0;
  158 
  159 #ifdef notdef
  160         /*
  161          * Turn on CP debugging
  162          */
  163         aap->aali_hostlog = 1;
  164 #endif
  165 
  166         /*
  167          * Build the initialization block
  168          */
  169         inp = &aap->aali_init;
  170         inp->init_numvcc = CP_WRITE(FORE_MAX_VCC);
  171         inp->init_cmd_elem = CP_WRITE(CMD_QUELEN);
  172         inp->init_xmit_elem = CP_WRITE(XMIT_QUELEN);
  173         inp->init_recv_elem = CP_WRITE(RECV_QUELEN);
  174         inp->init_recv_ext = CP_WRITE(RECV_EXTRA_SEGS);
  175         inp->init_xmit_ext = CP_WRITE(XMIT_EXTRA_SEGS);
  176         inp->init_buf1s.bfs_quelen = CP_WRITE(BUF1_SM_QUELEN);
  177         inp->init_buf1s.bfs_bufsize = CP_WRITE(BUF1_SM_SIZE);
  178         inp->init_buf1s.bfs_cppool = CP_WRITE(BUF1_SM_CPPOOL);
  179         inp->init_buf1s.bfs_entsize = CP_WRITE(BUF1_SM_ENTSIZE);
  180         inp->init_buf1l.bfs_quelen = CP_WRITE(BUF1_LG_QUELEN);
  181         inp->init_buf1l.bfs_bufsize = CP_WRITE(BUF1_LG_SIZE);
  182         inp->init_buf1l.bfs_cppool = CP_WRITE(BUF1_LG_CPPOOL);
  183         inp->init_buf1l.bfs_entsize = CP_WRITE(BUF1_LG_ENTSIZE);
  184         inp->init_buf2s.bfs_quelen = CP_WRITE(0);
  185         inp->init_buf2s.bfs_bufsize = CP_WRITE(0);
  186         inp->init_buf2s.bfs_cppool = CP_WRITE(0);
  187         inp->init_buf2s.bfs_entsize = CP_WRITE(0);
  188         inp->init_buf2l.bfs_quelen = CP_WRITE(0);
  189         inp->init_buf2l.bfs_bufsize = CP_WRITE(0);
  190         inp->init_buf2l.bfs_cppool = CP_WRITE(0);
  191         inp->init_buf2l.bfs_entsize = CP_WRITE(0);
  192 
  193         /*
  194          * Enable device interrupts
  195          */
  196         aap->aali_intr_ena = CP_WRITE(1);
  197 
  198         /*
  199          * Issue the Initialize command to the CP and wait for
  200          * the CP to interrupt to signal completion
  201          */
  202         inp->init_status = CP_WRITE(QSTAT_PENDING);
  203 
  204         if (!fup->fu_ft4) {
  205                 inp->init_cmd = CP_WRITE(CMD_INIT | CMD_INTR_REQ);
  206                 return;
  207         }
  208         inp->init_cmd = CP_WRITE(CMD_INIT);
  209 
  210         /*
  211          * With the ForeThought 4.X image it appears that we need to
  212          * busy wait on the initializisation command to complete.
  213          * Otherwise the command queue address (the first word
  214          * of the queue structure) will be mangled.
  215          */
  216         c = 0;
  217         for (wait = 0; wait < MAX_WAIT; wait++) {
  218                 c = CP_READ(inp->init_status);
  219                 if (c & QSTAT_COMPLETED)
  220                         break;
  221                 DELAY(1000);
  222         }
  223         if (c & QSTAT_ERROR) {
  224                 log(LOG_ERR, "fore initialization failed: intf=%s%d, "
  225                     "hbeat=0x%lx\n", fup->fu_pif.pif_name,
  226                     fup->fu_pif.pif_unit, (u_long)CP_READ(aap->aali_heartbeat));
  227                 fore_interface_free(fup);
  228                 return;
  229         }
  230         if (!(c & QSTAT_COMPLETED)) {
  231                 log(LOG_ERR, "fore initialization timed out: intf=%s%d, "
  232                     "hbeat=0x%lx\n", fup->fu_pif.pif_name, fup->fu_pif.pif_unit,
  233                     (u_long)CP_READ(aap->aali_heartbeat));
  234                 fore_interface_free(fup);
  235                 return;
  236         }
  237         fore_initialize_complete(fup);
  238         return;
  239 
  240 failed:
  241         /*
  242          * Initialization failure
  243          */
  244         fore_interface_free(fup);
  245         log(LOG_ERR, "fore initialization failed: intf=%s%d, err=%s\n",
  246                 fup->fu_pif.pif_name, fup->fu_pif.pif_unit, errmsg);
  247         return;
  248 }
  249 
  250 
  251 /*
  252  * Complete CP Initialization 
  253  *
  254  * Called after the CP has successfully completed processing of the 
  255  * Initialize command.  We will now finish off our part of the 
  256  * initialization process by setting up all the host-based queue 
  257  * management structures.
  258  *
  259  * Called at interrupt level.
  260  *
  261  * Arguments:
  262  *      fup             pointer to device unit structure
  263  *
  264  * Returns:
  265  *      none
  266  */
  267 void
  268 fore_initialize_complete(fup)
  269         Fore_unit       *fup;
  270 {
  271         Aali            *aap = fup->fu_aali;
  272 
  273         /*
  274          * Log an initialization failure
  275          */
  276         if (CP_READ(aap->aali_init.init_status) & QSTAT_ERROR) {
  277 
  278                 log(LOG_ERR, 
  279                         "fore initialization failed: intf=%s%d, hbeat=0x%lx\n",
  280                         fup->fu_pif.pif_name, fup->fu_pif.pif_unit,
  281                         (u_long)CP_READ(aap->aali_heartbeat));
  282                 return;
  283         }
  284 
  285         ATM_DEBUG1("heap=0x%lx\n", aap->aali_heap);
  286         ATM_DEBUG1("heaplen=0x%lx\n", aap->aali_heaplen);
  287         ATM_DEBUG1("cmd_q=0x%lx\n", aap->aali_cmd_q);
  288         ATM_DEBUG1("xmit_q=0x%lx\n", aap->aali_xmit_q);
  289         ATM_DEBUG1("recv_q=0x%lx\n", aap->aali_recv_q);
  290         ATM_DEBUG1("buf1s_q=0x%lx\n", aap->aali_buf1s_q);
  291         ATM_DEBUG1("buf1l_q=0x%lx\n", aap->aali_buf1l_q);
  292         ATM_DEBUG1("buf2s_q=0x%lx\n", aap->aali_buf2s_q);
  293         ATM_DEBUG1("buf2l_q=0x%lx\n", aap->aali_buf2l_q);
  294 
  295         /*
  296          * Initialize all of our queues
  297          */
  298         fore_xmit_initialize(fup);
  299         fore_recv_initialize(fup);
  300         fore_buf_initialize(fup);
  301         fore_cmd_initialize(fup);
  302 
  303         /*
  304          * Mark device initialization completed
  305          */
  306         fup->fu_flags |= CUF_INITED;
  307 
  308         fore_get_prom(fup);
  309         return;
  310 }
  311 
  312 
  313 /*
  314  * Get device PROM values from CP
  315  * 
  316  * This function will issue a GET_PROM command to the CP in order to
  317  * initiate the DMA transfer of the CP's PROM structure to the host.
  318  * This will be called after CP initialization has completed.
  319  * There is (currently) no retry if this fails.
  320  *
  321  * It took me some time to find out that FT3 and FT4 use different
  322  * operation codes for GET_PROM.
  323  *
  324  * Called at interrupt level.
  325  *
  326  * Arguments:
  327  *      fup     pointer to device unit structure
  328  *
  329  * Returns:
  330  *      none
  331  *
  332  */
  333 static void
  334 fore_get_prom(fup)
  335         Fore_unit       *fup;
  336 {
  337         H_cmd_queue     *hcp;
  338         Cmd_queue       *cqp;
  339 
  340         /*
  341          * Queue command at end of command queue
  342          */
  343         hcp = fup->fu_cmd_tail;
  344         if ((*hcp->hcq_status) & QSTAT_FREE) {
  345 
  346                 /*
  347                  * Queue entry available, so set our view of things up
  348                  */
  349                 if (fup->fu_ft4)
  350                         hcp->hcq_code = CMD_GET_PROM4;
  351                 else
  352                         hcp->hcq_code = CMD_GET_PROM;
  353                 hcp->hcq_arg = NULL;
  354                 fup->fu_cmd_tail = hcp->hcq_next;
  355 
  356                 /*
  357                  * Now set the CP-resident queue entry - the CP will grab
  358                  * the command when the op-code is set.
  359                  */
  360                 cqp = hcp->hcq_cpelem;
  361                 (*hcp->hcq_status) = QSTAT_PENDING;
  362 
  363                 fup->fu_promd = vtophys(fup->fu_prom);
  364                 if (fup->fu_promd == 0) {
  365                         fup->fu_stats->st_drv.drv_cm_nodma++;
  366                         return;
  367                 }
  368                 cqp->cmdq_prom.prom_buffer = (CP_dma) CP_WRITE(fup->fu_promd);
  369                 cqp->cmdq_prom.prom_cmd = CP_WRITE(hcp->hcq_code | CMD_INTR_REQ);
  370 
  371         } else {
  372                 /*
  373                  * Command queue full
  374                  */
  375                 fup->fu_stats->st_drv.drv_cm_full++;
  376         }
  377 
  378         return;
  379 }
  380 

Cache object: ce040a50f564b77a54c400b290c7c097


[ 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.