in horizon.c [1810:2027]
static int hrz_init(hrz_dev *dev)
{
int onefivefive;
u16 chan;
int buff_count;
HDW * mem;
cell_buf * tx_desc;
cell_buf * rx_desc;
u32 ctrl;
ctrl = rd_regl (dev, CONTROL_0_REG);
PRINTD (DBG_INFO, "ctrl0reg is %#x", ctrl);
onefivefive = ctrl & ATM_LAYER_STATUS;
if (onefivefive)
printk (DEV_LABEL ": Horizon Ultra (at 155.52 MBps)");
else
printk (DEV_LABEL ": Horizon (at 25 MBps)");
printk (":");
// Reset the card to get everything in a known state
printk (" reset");
hrz_reset (dev);
// Clear all the buffer memory
printk (" clearing memory");
for (mem = (HDW *) memmap; mem < (HDW *) (memmap + 1); ++mem)
wr_mem (dev, mem, 0);
printk (" tx channels");
// All transmit eight channels are set up as AAL5 ABR channels with
// a 16us cell spacing. Why?
// Channel 0 gets the free buffer at 100h, channel 1 gets the free
// buffer at 110h etc.
for (chan = 0; chan < TX_CHANS; ++chan) {
tx_ch_desc * tx_desc = &memmap->tx_descs[chan];
cell_buf * buf = &memmap->inittxbufs[chan];
// initialise the read and write buffer pointers
wr_mem (dev, &tx_desc->rd_buf_type, BUF_PTR(buf));
wr_mem (dev, &tx_desc->wr_buf_type, BUF_PTR(buf));
// set the status of the initial buffers to empty
wr_mem (dev, &buf->next, BUFF_STATUS_EMPTY);
}
// Use space bufn3 at the moment for tx buffers
printk (" tx buffers");
tx_desc = memmap->bufn3;
wr_mem (dev, &memmap->txfreebufstart.next, BUF_PTR(tx_desc) | BUFF_STATUS_EMPTY);
for (buff_count = 0; buff_count < BUFN3_SIZE-1; buff_count++) {
wr_mem (dev, &tx_desc->next, BUF_PTR(tx_desc+1) | BUFF_STATUS_EMPTY);
tx_desc++;
}
wr_mem (dev, &tx_desc->next, BUF_PTR(&memmap->txfreebufend) | BUFF_STATUS_EMPTY);
// Initialise the transmit free buffer count
wr_regw (dev, TX_FREE_BUFFER_COUNT_OFF, BUFN3_SIZE);
printk (" rx channels");
// Initialise all of the receive channels to be AAL5 disabled with
// an interrupt threshold of 0
for (chan = 0; chan < RX_CHANS; ++chan) {
rx_ch_desc * rx_desc = &memmap->rx_descs[chan];
wr_mem (dev, &rx_desc->wr_buf_type, CHANNEL_TYPE_AAL5 | RX_CHANNEL_DISABLED);
}
printk (" rx buffers");
// Use space bufn4 at the moment for rx buffers
rx_desc = memmap->bufn4;
wr_mem (dev, &memmap->rxfreebufstart.next, BUF_PTR(rx_desc) | BUFF_STATUS_EMPTY);
for (buff_count = 0; buff_count < BUFN4_SIZE-1; buff_count++) {
wr_mem (dev, &rx_desc->next, BUF_PTR(rx_desc+1) | BUFF_STATUS_EMPTY);
rx_desc++;
}
wr_mem (dev, &rx_desc->next, BUF_PTR(&memmap->rxfreebufend) | BUFF_STATUS_EMPTY);
// Initialise the receive free buffer count
wr_regw (dev, RX_FREE_BUFFER_COUNT_OFF, BUFN4_SIZE);
// Initialize Horizons registers
// TX config
wr_regw (dev, TX_CONFIG_OFF,
ABR_ROUND_ROBIN | TX_NORMAL_OPERATION | DRVR_DRVRBAR_ENABLE);
// RX config. Use 10-x VC bits, x VP bits, non user cells in channel 0.
wr_regw (dev, RX_CONFIG_OFF,
DISCARD_UNUSED_VPI_VCI_BITS_SET | NON_USER_CELLS_IN_ONE_CHANNEL | vpi_bits);
// RX line config
wr_regw (dev, RX_LINE_CONFIG_OFF,
LOCK_DETECT_ENABLE | FREQUENCY_DETECT_ENABLE | GXTALOUT_SELECT_DIV4);
// Set the max AAL5 cell count to be just enough to contain the
// largest AAL5 frame that the user wants to receive
wr_regw (dev, MAX_AAL5_CELL_COUNT_OFF,
DIV_ROUND_UP(max_rx_size + ATM_AAL5_TRAILER, ATM_CELL_PAYLOAD));
// Enable receive
wr_regw (dev, RX_CONFIG_OFF, rd_regw (dev, RX_CONFIG_OFF) | RX_ENABLE);
printk (" control");
// Drive the OE of the LEDs then turn the green LED on
ctrl |= GREEN_LED_OE | YELLOW_LED_OE | GREEN_LED | YELLOW_LED;
wr_regl (dev, CONTROL_0_REG, ctrl);
// Test for a 155-capable card
if (onefivefive) {
// Select 155 mode... make this a choice (or: how do we detect
// external line speed and switch?)
ctrl |= ATM_LAYER_SELECT;
wr_regl (dev, CONTROL_0_REG, ctrl);
// test SUNI-lite vs SAMBA
// Register 0x00 in the SUNI will have some of bits 3-7 set, and
// they will always be zero for the SAMBA. Ha! Bloody hardware
// engineers. It'll never work.
if (rd_framer (dev, 0) & 0x00f0) {
// SUNI
printk (" SUNI");
// Reset, just in case
wr_framer (dev, 0x00, 0x0080);
wr_framer (dev, 0x00, 0x0000);
// Configure transmit FIFO
wr_framer (dev, 0x63, rd_framer (dev, 0x63) | 0x0002);
// Set line timed mode
wr_framer (dev, 0x05, rd_framer (dev, 0x05) | 0x0001);
} else {
// SAMBA
printk (" SAMBA");
// Reset, just in case
wr_framer (dev, 0, rd_framer (dev, 0) | 0x0001);
wr_framer (dev, 0, rd_framer (dev, 0) &~ 0x0001);
// Turn off diagnostic loopback and enable line-timed mode
wr_framer (dev, 0, 0x0002);
// Turn on transmit outputs
wr_framer (dev, 2, 0x0B80);
}
} else {
// Select 25 mode
ctrl &= ~ATM_LAYER_SELECT;
// Madge B154 setup
// none required?
}
printk (" LEDs");
GREEN_LED_ON(dev);
YELLOW_LED_ON(dev);
printk (" ESI=");
{
u16 b = 0;
int i;
u8 * esi = dev->atm_dev->esi;
// in the card I have, EEPROM
// addresses 0, 1, 2 contain 0
// addresess 5, 6 etc. contain ffff
// NB: Madge prefix is 00 00 f6 (which is 00 00 6f in Ethernet bit order)
// the read_bia routine gets the BIA in Ethernet bit order
for (i=0; i < ESI_LEN; ++i) {
if (i % 2 == 0)
b = read_bia (dev, i/2 + 2);
else
b = b >> 8;
esi[i] = b & 0xFF;
printk ("%02x", esi[i]);
}
}
// Enable RX_Q and ?X_COMPLETE interrupts only
wr_regl (dev, INT_ENABLE_REG_OFF, INTERESTING_INTERRUPTS);
printk (" IRQ on");
printk (".\n");
return onefivefive;
}