void
m8xx_uart_smc_initialize (int minor)
{
    unsigned char brg;
    volatile m8xxSMCparms_t *smcparms = 0;
    volatile m8xxSMCRegisters_t *smcregs = 0;

    /*
     * Check that minor number is valid
     */
    if ( (minor < SMC1_MINOR) || (minor > SMC2_MINOR) )
        return;

    m8xx.sdcr = 0x01;                 /* as per section 16.10.2.1 MPC821UM/AD */
    /* Get the simode clock source bit values for 9600 bps */
    brg = m8xx_get_brg_clk(9600);

    /*
     * Allocate buffer descriptors
     */
    RxBd[minor] = m8xx_bd_allocate (1);
    TxBd[minor] = m8xx_bd_allocate (1);

    /*
     *  Get the address of the parameter RAM for the specified port,
     *  configure I/O port B and put SMC in NMSI mode, connect the
     *  SMC to the appropriate BRG.
     *
     *  SMC2 RxD is shared with port B bit 20
     *  SMC2 TxD is shared with port B bit 21
     *  SMC1 RxD is shared with port B bit 24
     *  SMC1 TxD is shared with port B bit 25
     */
    switch (minor) {
    case SMC1_MINOR:
        smcparms = &m8xx.smc1p;
        smcregs = &m8xx.smc1;

        m8xx.pbpar |=  0x000000C0;    /* PB24 & PB25 are dedicated peripheral pins */
        m8xx.pbdir &= ~0x000000C0;    /* PB24 & PB25 must not drive UART lines */
        m8xx.pbodr &= ~0x000000C0;    /* PB24 & PB25 are not open drain */

        m8xx.simode &= 0xFFFF0FFF;    /* Clear SMC1CS & SMC1 for NMSI mode */
        m8xx.simode |= brg << 12;     /* SMC1CS = brg */
        break;

    case SMC2_MINOR:
        smcparms = &m8xx.smc2p;
        smcregs = &m8xx.smc2;

        m8xx.pbpar |=  0x00000C00;    /* PB20 & PB21 are dedicated peripheral pins */
        m8xx.pbdir &= ~0x00000C00;    /* PB20 & PB21 must not drive the UART lines */
        m8xx.pbodr &= ~0x00000C00;    /* PB20 & PB21 are not open drain */

        m8xx.simode &= 0x0FFFFFFF;    /* Clear SMC2CS & SMC2 for NMSI mode */
        m8xx.simode |= brg << 28;     /* SMC2CS = brg */
        break;
    }

    /*
     * Set up SMC1 parameter RAM common to all protocols
     */
    smcparms->rbase = (char *)RxBd[minor] - (char *)&m8xx;
    smcparms->tbase = (char *)TxBd[minor] - (char *)&m8xx;
    smcparms->rfcr = M8xx_RFCR_MOT | M8xx_RFCR_DMA_SPACE(0);
    smcparms->tfcr = M8xx_TFCR_MOT | M8xx_TFCR_DMA_SPACE(0);
    if ( (mbx8xx_console_get_configuration() & 0x06) == 0x02 )
        smcparms->mrblr = RXBUFSIZE;    /* Maximum Rx buffer size */
    else
        smcparms->mrblr = 1;            /* Maximum Rx buffer size */

    /*
     * Set up SMC1 parameter RAM UART-specific parameters
     */
    smcparms->un.uart.max_idl = 10;   /* Set nb of idle chars to close buffer */
    smcparms->un.uart.brkcr = 0;      /* Set nb of breaks to send for STOP Tx */
    smcparms->un.uart.brkec = 0;      /* Clear break counter */

    /*
     * Set up the Receive Buffer Descriptor
     */
    RxBd[minor]->status = M8xx_BD_EMPTY | M8xx_BD_WRAP | M8xx_BD_INTERRUPT;
    RxBd[minor]->length = 0;
    RxBd[minor]->buffer = rxBuf[minor];

    /*
     * Setup the Transmit Buffer Descriptor
     */
    TxBd[minor]->status = M8xx_BD_WRAP;

    /*
     * Set up SMCx general and protocol-specific mode registers
     */
    smcregs->smce = ~0;               /* Clear any pending events */
    smcregs->smcm = 0;                /* Enable SMC Rx & Tx interrupts */
    smcregs->smcmr = M8xx_SMCMR_CLEN(9) | M8xx_SMCMR_SM_UART;

    /*
     * Send "Init parameters" command
     */
    switch (minor) {
    case SMC1_MINOR:
        m8xx_cp_execute_cmd (M8xx_CR_OP_INIT_RX_TX | M8xx_CR_CHAN_SMC1);
        break;

    case SMC2_MINOR:
        m8xx_cp_execute_cmd (M8xx_CR_OP_INIT_RX_TX | M8xx_CR_CHAN_SMC2);
        break;
    }

    /*
     * Enable receiver and transmitter
     */
    smcregs->smcmr |= M8xx_SMCMR_TEN | M8xx_SMCMR_REN;
    if ( (mbx8xx_console_get_configuration() & 0x06) == 0x02 ) {
        consoleIrqData.on = m8xx_smc_enable;
        consoleIrqData.off = m8xx_smc_disable;
        consoleIrqData.isOn = m8xx_smc_isOn;
        switch (minor) {
        case SMC1_MINOR:
            consoleIrqData.name = BSP_CPM_IRQ_SMC1;
            consoleIrqData.hdl  = m8xx_smc1_interrupt_handler;
            break;

        case SMC2_MINOR:
            consoleIrqData.name = BSP_CPM_IRQ_SMC2_OR_PIP;
            consoleIrqData.hdl  = m8xx_smc2_interrupt_handler;
            break;
        }
        if (!BSP_install_rtems_irq_handler (&consoleIrqData)) {
            printk("Unable to connect SMC Irq handler\n");
            rtems_fatal_error_occurred(1);
        }
    }
}
Пример #2
0
static void
sccInitialize (int chan)
{
  int i;
  /*
   * allocate buffers
   * FIXME: use a cache-line size boundary alloc here
   */
  rxBuf[chan] = malloc(sizeof(*rxBuf[chan]) + 2*PPC_CACHE_ALIGNMENT);
  if (rxBuf[chan] == NULL) {
    BSP_panic("Cannot allocate console rx buffer\n");
  }
  else {
    /*
     * round up rxBuf[chan] to start at a cache line size
     */
    rxBuf[chan] = (sccRxBuf_t *)
      (((uint32_t)rxBuf[chan]) +
       (PPC_CACHE_ALIGNMENT
	- ((uint32_t)rxBuf[chan]) % PPC_CACHE_ALIGNMENT));
  }
  /*
   * Allocate buffer descriptors
   */
  sccCurrRxBd[chan] =
    sccFrstRxBd[chan] = m8xx_bd_allocate(SCC_RXBD_CNT);
  sccPrepTxBd[chan] =
    sccDequTxBd[chan] =
    sccFrstTxBd[chan] = m8xx_bd_allocate(SCC_TXBD_CNT);
  switch(chan) {
  case CONS_CHN_SCC1:
    /*
     * Configure port A pins to enable TXD1 and RXD1 pins
     * FIXME: add setup for modem control lines....
     */
    m8xx.papar |=  0x03;
    m8xx.padir &= ~0x03;

    /*
     * Configure port C pins to enable RTS1 pins (static active low)
     */
    m8xx.pcpar &= ~0x01;
    m8xx.pcso  &= ~0x01;
    m8xx.pcdir |=  0x01;
    m8xx.pcdat &= ~0x01;
    break;
  case CONS_CHN_SCC2:
    /*
     * Configure port A pins to enable TXD2 and RXD2 pins
     * FIXME: add setup for modem control lines....
     */
    m8xx.papar |=  0x0C;
    m8xx.padir &= ~0x0C;

    /*
     * Configure port C pins to enable RTS2 pins (static active low)
     */
    m8xx.pcpar &= ~0x02;
    m8xx.pcso  &= ~0x02;
    m8xx.pcdir |=  0x02;
    m8xx.pcdat &= ~0x02;
    break;
  case CONS_CHN_SCC3:
    /*
     * Configure port A pins to enable TXD3 and RXD3 pins
     * FIXME: add setup for modem control lines....
     */
    m8xx.papar |=  0x30;
    m8xx.padir &= ~0x30;

    /*
     * Configure port C pins to enable RTS3 (static active low)
     */
    m8xx.pcpar &= ~0x04;
    m8xx.pcso  &= ~0x04;
    m8xx.pcdir |=  0x04;
    m8xx.pcdat &= ~0x04;
    break;
  case CONS_CHN_SCC4:
    /*
     * Configure port A pins to enable TXD4 and RXD4 pins
     * FIXME: add setup for modem control lines....
     */
    m8xx.papar |=  0xC0;
    m8xx.padir &= ~0xC0;

    /*
     * Configure port C pins to enable RTS4 pins (static active low)
     */
    m8xx.pcpar &= ~0x08;
    m8xx.pcso  &= ~0x08;
    m8xx.pcdir |=  0x08;
    m8xx.pcdat &= ~0x08;
    break;
  case CONS_CHN_SMC1:
    /*
     * Configure port B pins to enable SMTXD1 and SMRXD1 pins
     */
    m8xx.pbpar |=  0xC0;
    m8xx.pbdir &= ~0xC0;
    break;
  case CONS_CHN_SMC2:
    /*
     * Configure port B pins to enable SMTXD2 and SMRXD2 pins
     */
    m8xx.pbpar |=  0xC00;
    m8xx.pbdir &= ~0xC00;
    break;
  }
  /*
   * allocate and connect BRG
   */
  sccBRGalloc(chan,9600);


  /*
   * Set up SCCx parameter RAM common to all protocols
   */
  CHN_PARAM_SET(chan,rbase,(char *)sccFrstRxBd[chan] - (char *)&m8xx);
  CHN_PARAM_SET(chan,tbase,(char *)sccFrstTxBd[chan] - (char *)&m8xx);
  CHN_PARAM_SET(chan,rfcr ,M8xx_RFCR_MOT | M8xx_RFCR_DMA_SPACE(0));
  CHN_PARAM_SET(chan,tfcr ,M8xx_TFCR_MOT | M8xx_TFCR_DMA_SPACE(0));
  if (m8xx_scc_mode[chan] != TERMIOS_POLLED)
    CHN_PARAM_SET(chan,mrblr,RXBUFSIZE);
  else
    CHN_PARAM_SET(chan,mrblr,1);

  /*
   * Set up SCCx parameter RAM UART-specific parameters
   */
  CHN_PARAM_SET(chan,un.uart.max_idl ,MAX_IDL_DEFAULT);
  CHN_PARAM_SET(chan,un.uart.brkln   ,0);
  CHN_PARAM_SET(chan,un.uart.brkec   ,0);
  CHN_PARAM_SET(chan,un.uart.brkcr   ,0);
  if (m8xx_console_chan_desc[chan].is_scc) {
    m8xx_console_chan_desc[chan].parms.sccp->un.uart.character[0]=0x8000; /* no char filter */
    m8xx_console_chan_desc[chan].parms.sccp->un.uart.rccm=0x80FF; /* control character mask */
  }

  /*
   * Set up the Receive Buffer Descriptors
   */
  for (i = 0;i < SCC_RXBD_CNT;i++) {
    sccFrstRxBd[chan][i].status = M8xx_BD_EMPTY | M8xx_BD_INTERRUPT;
    if (i == SCC_RXBD_CNT-1) {
      sccFrstRxBd[chan][i].status |= M8xx_BD_WRAP;
    }
    sccFrstRxBd[chan][i].length = 0;
    sccFrstRxBd[chan][i].buffer = (*rxBuf[chan])[i];
  }
  /*
   * Setup the Transmit Buffer Descriptor
   */
  for (i = 0;i < SCC_TXBD_CNT;i++) {
    sccFrstTxBd[chan][i].status = M8xx_BD_INTERRUPT;
    if (i == SCC_TXBD_CNT-1) {
      sccFrstTxBd[chan][i].status |= M8xx_BD_WRAP;
    }
    sccFrstTxBd[chan][i].length = 0;
    sccFrstTxBd[chan][i].buffer = NULL;
  }

  /*
   * Set up SCC general and protocol-specific mode registers
   */
  CHN_EVENT_CLR(chan,~0);	/* Clear any pending events */
  CHN_MASK_SET(chan,0);	        /* Mask all interrupt/event sources */

  if (m8xx_console_chan_desc[chan].is_scc) {
    m8xx_console_chan_desc[chan].regs.sccr->psmr = 0xb000; /* 8N1, CTS flow control */
    m8xx_console_chan_desc[chan].regs.sccr->gsmr_h = 0x00000000;
    m8xx_console_chan_desc[chan].regs.sccr->gsmr_l = 0x00028004; /* UART mode */
  }
  else {
    m8xx_console_chan_desc[chan].regs.smcr->smcmr = 0x4820;
  }
  /*
   * Send "Init parameters" command
   */
  m8xx_cp_execute_cmd(M8xx_CR_OP_INIT_RX_TX
		      | m8xx_console_chan_desc[chan].cr_chan_code);

  /*
   * Enable receiver and transmitter
   */
  if (m8xx_console_chan_desc[chan].is_scc) {
    m8xx_console_chan_desc[chan].regs.sccr->gsmr_l |= 0x00000030;
  }
  else {
    m8xx_console_chan_desc[chan].regs.smcr->smcmr |= 0x0003;
  }

  if (m8xx_scc_mode[chan] != TERMIOS_POLLED) {

    rtems_irq_connect_data irq_conn_data = {
      m8xx_console_chan_desc[chan].ivec_src,
      sccInterruptHandler,         /* rtems_irq_hdl           */
      (rtems_irq_hdl_param)chan,   /* (rtems_irq_hdl_param)   */
      mpc8xx_console_irq_on,       /* (rtems_irq_enable)      */
      mpc8xx_console_irq_off,      /* (rtems_irq_disable)     */
      mpc8xx_console_irq_isOn      /* (rtems_irq_is_enabled)  */
    };
    if (!BSP_install_rtems_irq_handler (&irq_conn_data)) {
      rtems_panic("console: cannot install IRQ handler");
    }
  }
}
void
m8xx_uart_scc_initialize (int minor)
{
    unsigned char brg;
    volatile m8xxSCCparms_t *sccparms = 0;
    volatile m8xxSCCRegisters_t *sccregs = 0;

    /*
     * Check that minor number is valid
     */
    if ( (minor < SCC2_MINOR) || (minor > NUM_PORTS-1) )
        return;

    /* Get the sicr clock source bit values for 9600 bps */
    brg = m8xx_get_brg_clk(9600);

    /*
     * Allocate buffer descriptors
     */
    RxBd[minor] = m8xx_bd_allocate(1);
    TxBd[minor] = m8xx_bd_allocate(1);

    /*
     *  Get the address of the parameter RAM for the specified port,
     *  configure I/O port A,C & D and put SMC in NMSI mode, connect
     *  the SCC to the appropriate BRG.
     *
     *  SCC2 TxD is shared with port A bit 12
     *  SCC2 RxD is shared with port A bit 13
     *  SCC1 TxD is shared with port A bit 14
     *  SCC1 RxD is shared with port A bit 15
     *  SCC4 DCD is shared with port C bit 4
     *  SCC4 CTS is shared with port C bit 5
     *  SCC3 DCD is shared with port C bit 6
     *  SCC3 CTS is shared with port C bit 7
     *  SCC2 DCD is shared with port C bit 8
     *  SCC2 CTS is shared with port C bit 9
     *  SCC1 DCD is shared with port C bit 10
     *  SCC1 CTS is shared with port C bit 11
     *  SCC2 RTS is shared with port C bit 14
     *  SCC1 RTS is shared with port C bit 15
     *  SCC4 RTS is shared with port D bit 6
     *  SCC3 RTS is shared with port D bit 7
     *  SCC4 TxD is shared with port D bit 8
     *  SCC4 RxD is shared with port D bit 9
     *  SCC3 TxD is shared with port D bit 10
     *  SCC3 RxD is shared with port D bit 11
     */
    switch (minor) {
    case SCC2_MINOR:
        sccparms = &m8xx.scc2p;
        sccregs = &m8xx.scc2;

        m8xx.papar |=  0x000C;        /* PA12 & PA13 are dedicated peripheral pins */
        m8xx.padir &= ~0x000C;        /* PA13 & PA12 must not drive the UART lines */
        m8xx.paodr &= ~0x000C;        /* PA12 & PA13 are not open drain */
        m8xx.pcpar |=  0x0002;        /* PC14 is SCC2 RTS */
        m8xx.pcpar &= ~0x00C0;        /* PC8 & PC9 are SCC2 DCD and CTS */
        m8xx.pcdir &= ~0x00C2;        /* PC8, PC9 & PC14 must not drive the UART lines */
        m8xx.pcso  |=  0x00C0;        /* Enable DCD and CTS inputs */

        m8xx.sicr &= 0xFFFF00FF;      /* Clear TCS2 & RCS2, GR2=no grant, SC2=NMSI mode */
        m8xx.sicr |= (brg<<11) | (brg<<8); /* TCS2 = RCS2 = brg */
        break;

#ifdef mpc860
    case SCC3_MINOR:
        sccparms = &m8xx.scc3p;
        sccregs = &m8xx.scc3;

        m8xx.pcpar &= ~0x0300;        /* PC6 & PC7 are SCC3 DCD and CTS */
        m8xx.pcdir &= ~0x0300;        /* PC6 & PC7 must not drive the UART lines */
        m8xx.pcso  |=  0x0300;        /* Enable DCD and CTS inputs */
        m8xx.pdpar |=  0x0130;        /* PD7, PD10 & PD11 are dedicated peripheral pins */

        m8xx.sicr &= 0xFF00FFFF;      /* Clear TCS3 & RCS3, GR3=no grant, SC3=NMSI mode */
        m8xx.sicr |= (brg<<19) | (brg<<16); /* TCS3 = RCS3 = brg */
        break;

    case SCC4_MINOR:
        sccparms = &m8xx.scc4p;
        sccregs = &m8xx.scc4;

        m8xx.pcpar &= ~0x0C00;        /* PC4 & PC5 are SCC4 DCD and CTS */
        m8xx.pcdir &= ~0x0C00;        /* PC4 & PC5 must not drive the UART lines */
        m8xx.pcso  |=  0x0C00;        /* Enable DCD and CTS inputs */
        m8xx.pdpar |=  0x02C0;        /* PD6, PD8 & PD9 are dedicated peripheral pins */

        m8xx.sicr &= 0x00FFFFFF;      /* Clear TCS4 & RCS4, GR4=no grant, SC4=NMSI mode */
        m8xx.sicr |= (brg<<27) | (brg<<24); /* TCS4 = RCS4 = brg */
        break;
#endif
    }

    /*
     *  Set up SDMA
     */
    m8xx.sdcr = 0x01;                 /* as per section 16.10.2.1 MPC821UM/AD */

    /*
     *  Set up the SCC parameter RAM.
     */
    sccparms->rbase = (char *)RxBd[minor] - (char *)&m8xx;
    sccparms->tbase = (char *)TxBd[minor] - (char *)&m8xx;

    sccparms->rfcr = M8xx_RFCR_MOT | M8xx_RFCR_DMA_SPACE(0);
    sccparms->tfcr = M8xx_TFCR_MOT | M8xx_TFCR_DMA_SPACE(0);
    if ( (mbx8xx_console_get_configuration() & 0x06) == 0x02 )
        sccparms->mrblr = RXBUFSIZE;    /* Maximum Rx buffer size */
    else
        sccparms->mrblr = 1;            /* Maximum Rx buffer size */
    sccparms->un.uart.max_idl = 10;   /* Set nb of idle chars to close buffer */
    sccparms->un.uart.brkcr = 0;      /* Set nb of breaks to send for STOP Tx */

    sccparms->un.uart.parec = 0;      /* Clear parity error counter */
    sccparms->un.uart.frmec = 0;      /* Clear framing error counter */
    sccparms->un.uart.nosec = 0;      /* Clear noise counter */
    sccparms->un.uart.brkec = 0;      /* Clear break counter */

    sccparms->un.uart.uaddr[0] = 0;   /* Not in multidrop mode, so clear */
    sccparms->un.uart.uaddr[1] = 0;   /* Not in multidrop mode, so clear */
    sccparms->un.uart.toseq  = 0;     /* Tx Out-Of-SEQuence--no XON/XOFF now */

    sccparms->un.uart.character[0] = 0x8000; /* Entry is invalid */
    sccparms->un.uart.character[1] = 0x8000; /* Entry is invalid */
    sccparms->un.uart.character[2] = 0x8000; /* Entry is invalid */
    sccparms->un.uart.character[3] = 0x8000; /* Entry is invalid */
    sccparms->un.uart.character[4] = 0x8000; /* Entry is invalid */
    sccparms->un.uart.character[5] = 0x8000; /* Entry is invalid */
    sccparms->un.uart.character[6] = 0x8000; /* Entry is invalid */
    sccparms->un.uart.character[7] = 0x8000; /* Entry is invalid */


    sccparms->un.uart.rccm = 0xc0ff;  /* No masking */

    /*
     * Set up the Receive Buffer Descriptor
     */
    RxBd[minor]->status = M8xx_BD_EMPTY | M8xx_BD_WRAP | M8xx_BD_INTERRUPT;
    RxBd[minor]->length = 0;
    RxBd[minor]->buffer = rxBuf[minor];

    /*
     * Setup the Transmit Buffer Descriptor
     */
    TxBd[minor]->status = M8xx_BD_WRAP;

    /*
      * Set up SCCx general and protocol-specific mode registers
      */
    sccregs->gsmr_h = 0x00000020;     /* RFW=low latency operation */
    sccregs->gsmr_l = 0x00028004;     /* TDCR=RDCR=16x clock mode, MODE=uart*/
    sccregs->scce = ~0;               /* Clear any pending event */
    sccregs->sccm = 0;                /* Mask all interrupt/event sources */
    sccregs->psmr = 0x3000;           /* Normal operation & mode, 1 stop bit,
                                       8 data bits, no parity */
    sccregs->dsr = 0x7E7E;            /* No fractional stop bits */
    sccregs->gsmr_l = 0x00028034;     /* ENT=enable Tx, ENR=enable Rx */

    /*
     *  Initialize the Rx and Tx with the new parameters.
     */
    switch (minor) {
    case SCC2_MINOR:
        m8xx_cp_execute_cmd (M8xx_CR_OP_INIT_RX_TX | M8xx_CR_CHAN_SCC2);
        break;

#ifdef mpc860
    case SCC3_MINOR:
        m8xx_cp_execute_cmd (M8xx_CR_OP_INIT_RX_TX | M8xx_CR_CHAN_SCC3);
        break;
    case SCC4_MINOR:
        m8xx_cp_execute_cmd (M8xx_CR_OP_INIT_RX_TX | M8xx_CR_CHAN_SCC4);
        break;
#endif
    }
    if ( (mbx8xx_console_get_configuration() & 0x06) == 0x02 ) {
        consoleIrqData.on = m8xx_scc_enable;
        consoleIrqData.off = m8xx_scc_disable;
        consoleIrqData.isOn = m8xx_scc_isOn;

        switch (minor) {
        case SCC2_MINOR:
            consoleIrqData.name = BSP_CPM_IRQ_SCC2;
            consoleIrqData.hdl = m8xx_scc2_interrupt_handler;
            break;

#ifdef mpc860
        case SCC3_MINOR:
            consoleIrqData.name = BSP_CPM_IRQ_SCC3;
            consoleIrqData.hdl = m8xx_scc3_interrupt_handler;
            break;

        case SCC4_MINOR:
            consoleIrqData.name = BSP_CPM_IRQ_SCC4;
            consoleIrqData.hdl = m8xx_scc4_interrupt_handler;
            break;
#endif /* mpc860 */
        }
        if (!BSP_install_rtems_irq_handler (&consoleIrqData)) {
            printk("Unable to connect SCC Irq handler\n");
            rtems_fatal_error_occurred(1);
        }
    }
}
Пример #4
0
/*
 * Initialize the ethernet hardware
 */
static void
m8xx_enet_initialize (struct m8xx_enet_struct *sc)
{
  int i;
  unsigned char *hwaddr;

  /*
   * Configure port A
   * PA15 is enet RxD. Set PAPAR(15) to 1, PADIR(15) to 0.
   * PA14 is enet TxD. Set PAPAR(14) to 1, PADIR(14) to 0, PAODR(14) to 0.
   * PA7 is input CLK1. Set PAPAR(7) to 1, PADIR(7) to 0.
   * PA6 is input CLK2. Set PAPAR(6) to 1, PADIR(6) to 0.
   */
  m8xx.papar |=  0x303;
  m8xx.padir &= ~0x303;
  m8xx.paodr &= ~0x2;

  /*
   * Configure port C
   * PC11 is CTS1*. Set PCPAR(11) to 0, PCDIR(11) to 0, and PCSO(11) to 1.
   * PC10 is CD1*. Set PCPAR(10) to 0, PCDIR(10) to 0, and PCSO(10) to 1.
   */
  m8xx.pcpar &= ~0x30;
  m8xx.pcdir &= ~0x30;
  m8xx.pcso  |=  0x30;

  /*
   * Connect CLK1 and CLK2 to SCC1 in the SICR.
   * CLK1 is TxClk, CLK2 is RxClk. No grant mechanism, SCC1 is directly
   * connected to the NMSI pins.
   * R1CS = 0b101 (CLK2)
   * T1CS = 0b100 (CLK1)
   */
  m8xx.sicr |= 0x2C;

  /*
   * Initialize SDMA configuration register
   */
  m8xx.sdcr = 1;

  /*
   * Allocate mbuf pointers
   */
  sc->rxMbuf = malloc (sc->rxBdCount * sizeof *sc->rxMbuf,
		       M_MBUF, M_NOWAIT);
  sc->txMbuf = malloc (sc->txBdCount * sizeof *sc->txMbuf,
		       M_MBUF, M_NOWAIT);
  if (!sc->rxMbuf || !sc->txMbuf)
    rtems_panic ("No memory for mbuf pointers");

  /*
   * Set receiver and transmitter buffer descriptor bases
   */
  sc->rxBdBase = m8xx_bd_allocate(sc->rxBdCount);
  sc->txBdBase = m8xx_bd_allocate(sc->txBdCount);
  m8xx.scc1p.rbase = (char *)sc->rxBdBase - (char *)&m8xx;
  m8xx.scc1p.tbase = (char *)sc->txBdBase - (char *)&m8xx;

  /*
   * Send "Init parameters" command
   */
  m8xx_cp_execute_cmd (M8xx_CR_OP_INIT_RX_TX | M8xx_CR_CHAN_SCC1);

  /*
   * Set receive and transmit function codes
   */
  m8xx.scc1p.rfcr = M8xx_RFCR_MOT | M8xx_RFCR_DMA_SPACE(0);
  m8xx.scc1p.tfcr = M8xx_TFCR_MOT | M8xx_TFCR_DMA_SPACE(0);

  /*
   * Set maximum receive buffer length
   */
  m8xx.scc1p.mrblr = RBUF_SIZE;

  /*
   * Set CRC parameters
   */
  m8xx.scc1p.un.ethernet.c_pres = 0xFFFFFFFF;
  m8xx.scc1p.un.ethernet.c_mask = 0xDEBB20E3;

  /*
   * Clear diagnostic counters
   */
  m8xx.scc1p.un.ethernet.crcec = 0;
  m8xx.scc1p.un.ethernet.alec = 0;
  m8xx.scc1p.un.ethernet.disfc = 0;

  /*
   * Set pad value
   */
  m8xx.scc1p.un.ethernet.pads = 0x8888;

  /*
   * Set retry limit
   */
  m8xx.scc1p.un.ethernet.ret_lim = 15;

  /*
   * Set maximum and minimum frame length
   */
  m8xx.scc1p.un.ethernet.mflr = 1518;
  m8xx.scc1p.un.ethernet.minflr = 64;
  m8xx.scc1p.un.ethernet.maxd1 = MAX_MTU_SIZE;
  m8xx.scc1p.un.ethernet.maxd2 = MAX_MTU_SIZE;

  /*
   * Clear group address hash table
   */
  m8xx.scc1p.un.ethernet.gaddr1 = 0;
  m8xx.scc1p.un.ethernet.gaddr2 = 0;
  m8xx.scc1p.un.ethernet.gaddr3 = 0;
  m8xx.scc1p.un.ethernet.gaddr4 = 0;

  /*
   * Set our physical address
   */
  hwaddr = sc->arpcom.ac_enaddr;

  m8xx.scc1p.un.ethernet.paddr_h = (hwaddr[5] << 8) | hwaddr[4];
  m8xx.scc1p.un.ethernet.paddr_m = (hwaddr[3] << 8) | hwaddr[2];
  m8xx.scc1p.un.ethernet.paddr_l = (hwaddr[1] << 8) | hwaddr[0];

  /*
   * Aggressive retry
   */
  m8xx.scc1p.un.ethernet.p_per = 0;

  /*
   * Clear individual address hash table
   */
  m8xx.scc1p.un.ethernet.iaddr1 = 0;
  m8xx.scc1p.un.ethernet.iaddr2 = 0;
  m8xx.scc1p.un.ethernet.iaddr3 = 0;
  m8xx.scc1p.un.ethernet.iaddr4 = 0;

  /*
   * Clear temp address
   */
  m8xx.scc1p.un.ethernet.taddr_l = 0;
  m8xx.scc1p.un.ethernet.taddr_m = 0;
  m8xx.scc1p.un.ethernet.taddr_h = 0;

  /*
   * Set up receive buffer descriptors
   */
  for (i = 0 ; i < sc->rxBdCount ; i++) {
    (sc->rxBdBase + i)->status = 0;
  }

  /*
   * Set up transmit buffer descriptors
   */
  for (i = 0 ; i < sc->txBdCount ; i++) {
    (sc->txBdBase + i)->status = 0;
    sc->txMbuf[i] = NULL;
  }
  sc->txBdHead = sc->txBdTail = 0;
  sc->txBdActiveCount = 0;

  /*
   * Clear any outstanding events
   */
  m8xx.scc1.scce = 0xFFFF;

  /*
   * Set up interrupts
   */
  if (!BSP_install_rtems_irq_handler (&ethernetSCC1IrqData)) {
    rtems_panic ("Can't attach M8xx SCC1 interrupt handler\n");
  }
  m8xx.scc1.sccm = 0;     /* No interrupts unmasked till necessary */

  /*
   * Set up General SCC Mode Register
   * Ethernet configuration
   */
  m8xx.scc1.gsmr_h = 0x0;
  m8xx.scc1.gsmr_l = 0x1088000c;

  /*
   * Set up data synchronization register
   * Ethernet synchronization pattern
   */
  m8xx.scc1.dsr = 0xd555;

  /*
   * Set up protocol-specific mode register
   *      No Heartbeat check
   *      No force collision
   *      Discard short frames
   *      Individual address mode
   *      Ethernet CRC
   *      Not promisuous
   *      Ignore/accept broadcast packets as specified
   *      Normal backoff timer
   *      No loopback
   *      No input sample at end of frame
   *      64-byte limit for late collision
   *      Wait 22 bits before looking for start of frame delimiter
   *      Disable full-duplex operation
   */
  m8xx.scc1.psmr = 0x080A | (sc->acceptBroadcast ? 0 : 0x100);

  /*
   * Enable the TENA (RTS1*) pin
   */
  m8xx.pcpar |=  0x1;
  m8xx.pcdir &= ~0x1;

  /*
   * Enable receiver and transmitter
   */
  m8xx.scc1.gsmr_l = 0x1088003c;
}