void * M360AllocateRiscTimers (int count) { /* * Convert the count to the number of buffer descriptors * of equal or larger size. This ensures that all buffer * descriptors are allocated with appropriate alignment. */ return M360AllocateBufferDescriptors (((count * 4) + sizeof(m360BufferDescriptor_t) - 1) / sizeof(m360BufferDescriptor_t)); }
/*=========================================================================*\ | Function: | \*-------------------------------------------------------------------------*/ rtems_status_code m360_spi_init ( /*-------------------------------------------------------------------------*\ | Purpose: | | initialize the driver | +---------------------------------------------------------------------------+ | Input Parameters: | \*-------------------------------------------------------------------------*/ rtems_libi2c_bus_t *bh /* bus specifier structure */ ) /*-------------------------------------------------------------------------*\ | Return Value: | | o = ok or error code | \*=========================================================================*/ { m360_spi_softc_t *softc_ptr = &(((m360_spi_desc_t *)(bh))->softc); rtems_status_code rc = RTEMS_SUCCESSFUL; #if defined(DEBUG) printk("m360_spi_init called... "); #endif /* * init HW registers: */ /* * FIXME: set default mode in SPMODE */ /* * allocate BDs (1x RX, 1x TX) */ if (rc == RTEMS_SUCCESSFUL) { softc_ptr->rx_bd = M360AllocateBufferDescriptors (1); softc_ptr->tx_bd = M360AllocateBufferDescriptors (1); if ((softc_ptr->rx_bd == NULL) || (softc_ptr->tx_bd == NULL)) { rc = RTEMS_NO_MEMORY; } } /* * set parameter RAM */ m360.spip.rbase = (char *)softc_ptr->rx_bd - (char *)&m360; m360.spip.tbase = (char *)softc_ptr->tx_bd - (char *)&m360; m360.spip.rfcr = M360_RFCR_MOT | M360_RFCR_DMA_SPACE; m360.spip.tfcr = M360_RFCR_MOT | M360_RFCR_DMA_SPACE; m360.spip.mrblr = 2; /* * issue "InitRxTx" Command to CP */ M360ExecuteRISC (M360_CR_OP_INIT_RX_TX | M360_CR_CHAN_SPI); /* * init interrupt stuff */ if (rc == RTEMS_SUCCESSFUL) { m360_spi_install_irq_handler(softc_ptr,TRUE); } if (rc == RTEMS_SUCCESSFUL) { /* * set up ports * LINE PAR DIR DAT * ----------------------- * MOSI 1 1 x * MISO 1 1 x * CLK 1 1 x */ /* set Port B Pin Assignment Register... */ m360.pbpar = m360.pbpar | M360_PB_SPI_MISO_MSK | M360_PB_SPI_MOSI_MSK | M360_PB_SPI_CLK_MSK; /* set Port B Data Direction Register... */ m360.pbdir = m360.pbdir | M360_PB_SPI_MISO_MSK | M360_PB_SPI_MOSI_MSK | M360_PB_SPI_CLK_MSK; } /* * mark, that we have initialized */ if (rc == RTEMS_SUCCESSFUL) { softc_ptr->initialized = TRUE; } #if defined(DEBUG) printk("... exit OK\r\n"); #endif return rc; }
/* * Initialize the ethernet hardware */ static void m360Enet_initialize_hardware (struct scc_softc *sc) { int i; unsigned char *hwaddr; rtems_status_code status; rtems_isr_entry old_handler; /* * Configure port A CLK1, CLK2, TXD1 and RXD1 pins */ m360.papar |= 0x303; m360.padir &= ~0x303; m360.paodr &= ~0x303; /* * Configure port C CTS1* and CD1* pins */ m360.pcpar &= ~0x30; m360.pcdir &= ~0x30; m360.pcso |= 0x30; /* * Connect CLK1 and CLK2 to SCC1 */ m360.sicr &= ~0xFF; m360.sicr |= (5 << 3) | 4; /* * 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 = M360AllocateBufferDescriptors(sc->rxBdCount); sc->txBdBase = M360AllocateBufferDescriptors(sc->txBdCount); m360.scc1p.rbase = (char *)sc->rxBdBase - (char *)&m360; m360.scc1p.tbase = (char *)sc->txBdBase - (char *)&m360; /* * Send "Init parameters" command */ M360ExecuteRISC (M360_CR_OP_INIT_RX_TX | M360_CR_CHAN_SCC1); /* * Set receive and transmit function codes */ m360.scc1p.rfcr = M360_RFCR_MOT | M360_RFCR_DMA_SPACE; m360.scc1p.tfcr = M360_TFCR_MOT | M360_TFCR_DMA_SPACE; /* * Set maximum receive buffer length */ m360.scc1p.mrblr = RBUF_SIZE; /* * Set CRC parameters */ m360.scc1p.un.ethernet.c_pres = 0xFFFFFFFF; m360.scc1p.un.ethernet.c_mask = 0xDEBB20E3; /* * Clear diagnostic counters */ m360.scc1p.un.ethernet.crcec = 0; m360.scc1p.un.ethernet.alec = 0; m360.scc1p.un.ethernet.disfc = 0; /* * Set pad value */ m360.scc1p.un.ethernet.pads = 0x8888; /* * Set retry limit */ m360.scc1p.un.ethernet.ret_lim = 15; /* * Set maximum and minimum frame length */ m360.scc1p.un.ethernet.mflr = 1518; m360.scc1p.un.ethernet.minflr = 64; m360.scc1p.un.ethernet.maxd1 = RBUF_SIZE; m360.scc1p.un.ethernet.maxd2 = RBUF_SIZE; /* * Clear group address hash table */ m360.scc1p.un.ethernet.gaddr1 = 0; m360.scc1p.un.ethernet.gaddr2 = 0; m360.scc1p.un.ethernet.gaddr3 = 0; m360.scc1p.un.ethernet.gaddr4 = 0; /* * Set our physical address */ hwaddr = sc->arpcom.ac_enaddr; m360.scc1p.un.ethernet.paddr_h = (hwaddr[5] << 8) | hwaddr[4]; m360.scc1p.un.ethernet.paddr_m = (hwaddr[3] << 8) | hwaddr[2]; m360.scc1p.un.ethernet.paddr_l = (hwaddr[1] << 8) | hwaddr[0]; /* * Aggressive retry */ m360.scc1p.un.ethernet.p_per = 0; /* * Clear individual address hash table */ m360.scc1p.un.ethernet.iaddr1 = 0; m360.scc1p.un.ethernet.iaddr2 = 0; m360.scc1p.un.ethernet.iaddr3 = 0; m360.scc1p.un.ethernet.iaddr4 = 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 */ m360.scc1.scce = 0xFFFF; /* * Set up interrupts */ status = rtems_interrupt_catch (m360Enet_interrupt_handler, (m360.cicr & 0xE0) | 0x1E, &old_handler); if (status != RTEMS_SUCCESSFUL) rtems_panic ("Can't attach M360 SCC1 interrupt handler: %s\n", rtems_status_text (status)); m360.scc1.sccm = 0; /* No interrupts unmasked till necessary */ m360.cimr |= (1UL << 30); /* Enable SCC1 interrupt */ /* * Set up General SCC Mode Register * Ethernet configuration */ m360.scc1.gsmr_h = 0x0; m360.scc1.gsmr_l = 0x1088000c; /* * Set up data synchronization register * Ethernet synchronization pattern */ m360.scc1.dsr = 0xd555; /* * Set up protocol-specific mode register * 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 */ m360.scc1.psmr = 0x880A | (sc->acceptBroadcast ? 0 : 0x100); /* * Enable the TENA (RTS1*) pin */ #if (defined (M68360_ATLAS_HSB)) m360.pbpar |= 0x1000; m360.pbdir |= 0x1000; #else m360.pcpar |= 0x1; m360.pcdir &= ~0x1; #endif }
static int smc1Initialize (int major, int minor, void *arg) { /* * Allocate buffer descriptors */ smcRxBd = M360AllocateBufferDescriptors (1); smcTxBd = M360AllocateBufferDescriptors (1); /* * Configure port B pins to enable SMTXD1 and SMRXD1 pins */ m360.pbpar |= 0xC0; m360.pbdir &= ~0xC0; m360.pbodr &= ~0xC0; /* * Set up BRG1 (9,600 baud) */ m360.brgc1 = M360_BRG_RST; m360.brgc1 = smc1BRGC (console_baud_rate); /* * Put SMC1 in NMSI mode, connect SMC1 to BRG1 */ m360.simode |= M360_SI_SMC1_BRG1; /* * Set up SMC1 parameter RAM common to all protocols */ m360.smc1p.rbase = (char *)smcRxBd - (char *)&m360; m360.smc1p.tbase = (char *)smcTxBd - (char *)&m360; m360.smc1p.rfcr = M360_RFCR_MOT | M360_RFCR_DMA_SPACE; m360.smc1p.tfcr = M360_TFCR_MOT | M360_TFCR_DMA_SPACE; if (m360_smc1_interrupt) m360.smc1p.mrblr = RXBUFSIZE; else m360.smc1p.mrblr = 1; /* * Set up SMC1 parameter RAM UART-specific parameters */ m360.smc1p.un.uart.max_idl = 10; m360.smc1p.un.uart.brklen = 0; m360.smc1p.un.uart.brkec = 0; m360.smc1p.un.uart.brkcr = 0; /* * Set up the Receive Buffer Descriptor */ smcRxBd->status = M360_BD_EMPTY | M360_BD_WRAP | M360_BD_INTERRUPT; smcRxBd->length = 0; smcRxBd->buffer = rxBuf; /* * Setup the Transmit Buffer Descriptor */ smcTxBd->status = M360_BD_WRAP; /* * Set up SMC1 general and protocol-specific mode registers */ m360.smc1.smce = ~0; /* Clear any pending events */ m360.smc1.smcm = 0; /* Mask all interrupt/event sources */ m360.smc1.smcmr = M360_SMCMR_CLEN(9) | M360_SMCMR_SM_UART; /* * Send "Init parameters" command */ M360ExecuteRISC (M360_CR_OP_INIT_RX_TX | M360_CR_CHAN_SMC1); /* * Enable receiver and transmitter */ m360.smc1.smcmr |= M360_SMCMR_TEN | M360_SMCMR_REN; if (m360_smc1_interrupt) { rtems_isr_entry old_handler; (void) rtems_interrupt_catch (smc1InterruptHandler, (m360.cicr & 0xE0) | 0x04, &old_handler); m360.smc1.smcm = 3; /* Enable SMC1 TX and RX interrupts */ m360.cimr |= 1UL << 4; /* Enable SMC1 interrupts */ } return 0; }