IXP425: help on HSS channelized service

Davide Di Gesualdo davide.digesualdo at kaskonetworks.it
Tue Nov 24 08:29:37 EST 2009


Hi all,
I'm writing a kernel module for a HSS channelized service on IXP425 
processor, based on ixp4xx_hss. I'm developing on a IXDPG425 Intel 
board, and the HSS bus is attached to four Si3210 ProSLIC chips.
The purpose of this module is to read/write from/to HSS 8-byte buffers 
in raw mode (no particular alignment is required). In write direction, 
everything seems ok: if I write a buffer like
char buf[] = {0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb};
on a fixed timeslot and then read the TXD pin signal with a scope, I can 
see the correct waveform at the correct place; I've also tried to write 
a tone with a fixed freqeuncy, and I've listened it correctly.
The problem comes with read direction: I've tried to make a loopback by 
copying the rxbuffer in the txbuffer, but I can't hear my voice back 
(instead I hear something like a continous buzz). I'm quite sure I read 
the rxbuffer in the correct way (I do the same when I write txbuffer, 
which works properly!). This is the ISR for HSS read-complete interrupt:

static void hss_chan_irq(void *pdev)
{
	struct port *port = pdev;
	int ch, bytes_received;
	unsigned int first, errors, tx_list, rx_offset, v;
	char *rx_buf, *tx_buf;

	spin_lock(&npe_lock);
	while ((v = qmgr_get_entry(queue_ids[port->id].chan))) {
		first = v >> 24;
		errors = (v >> 16) & 0xFF;
		tx_list = (v >> 8) & 0xFF;
		rx_offset = v & 0xFF;

		BUG_ON(rx_offset % CHAN_RX_TRIGGER);
		BUG_ON(rx_offset >= CHAN_RX_FRAMES);
		BUG_ON(tx_list >= CHAN_TX_LISTS);

		bytes_received = rx_offset - port->chan_current_rx;
		if(bytes_received < 0)
			bytes_received += CHAN_RX_FRAMES;

		dma_sync_single(port->dev, port->chan_rx_buf_phys, 
chan_rx_buf_len(port), DMA_FROM_DEVICE);

		while(bytes_received >= CHAN_RX_TRIGGER) {
			if(port->chan_current_rx >= CHAN_RX_FRAMES)
				port->chan_current_rx = 0;
	
			if(port->chan_current_tx >= CHAN_TX_FRAMES)
				port->chan_current_tx = 0;

			for(ch = 0; ch < MAX_CHAN_DEVICES; ch++) {
				if(port->chan_devices[ch]->opened) {
					tx_buf = chan_tx_buf(port) + port->chan_current_tx + 
(CHAN_TX_FRAMES * port->chan_devices[ch]->timeslot);
					rx_buf = chan_rx_buf(port) + port->chan_current_rx + 
(CHAN_RX_FRAMES * port->chan_devices[ch]->timeslot);

					memcpy(tx_buf, rx_buf, CHAN_RX_TRIGGER);
				}
			}
			bytes_received -= CHAN_RX_TRIGGER;
			port->chan_current_rx += CHAN_RX_TRIGGER;
			port->chan_current_tx += CHAN_RX_TRIGGER;
		}
		dma_sync_single(port->dev, port->chan_tx_buf_phys, 
chan_tx_buf_len(port), DMA_TO_DEVICE);
	}
	spin_unlock(&npe_lock);
}

with buffers configuration as follow:

#define MIN_FRAME_SIZE		16
#define MAX_FRAME_SIZE		256
#define MAX_CHANNELS		(MAX_FRAME_SIZE / 8)
#define MAX_CHAN_DEVICES	32

#define CHAN_RX_TRIGGER		8
#define CHAN_RX_FRAMES		128
#define CHAN_TX_LIST_FRAMES	32
#define CHAN_TX_LISTS		4
#define CHAN_TX_FRAMES		(CHAN_TX_LIST_FRAMES * CHAN_TX_LISTS)

port->chan_current_rx is initialized as 0, port->chan_current_tx is 
initialized as 16; all 32 timeslots are configured as VOICE64K; the NPE 
configuration functions are the ones coded by Krzysztof Halasa.

Any suggestion would be really appreciated!
Thanks,

Davide Di Gesualdo

-- 
Davide Di Gesualdo
Kasko Networks S.r.l.
P.zza Regina Margherita, 7
L'Aquila (AQ) - CAP 67100 - Italy
Labs: +39 0862200460
Mobile: +39 3206203127
VoIP: +39 0857993233
Skype: davide.digesualdo



More information about the linux-arm-kernel mailing list