function receive frame
allocate an input buffer;
if no memory available then
return failure;
end if;
read the read buffer space available register;
if read buffer is empty then
return an error;
end if;
write frame length into buffer size register;
if mode is legacy then
send SPI read command;
end if;
while read buffer is not empty do
read read buffer;
extract Ethernet frame from your frame buffer;
update any read statistics;
end while;
return success;
end function;
function transmit frame do
read the write buffer space available register;
while transmit queue is not empty and write buffer space is available do
encapsulate transmit frame;
write transmit frame to write buffer;
update transmit statistics;
if error then
return failure;
end if;
update transmit statistics;
remove frame from transmit queue;
end while;
return success;
end function;
The interrupt service routine suspends, waiting for an interrupt from the QCA7000. Use of an interrupt means that the host need not continuously poll the SPI status and space available registers to detect if an operation has completed successfully before starting the next operation. Once an interrupt is detected by the host, this routine disables further interrupts and determines shy the interrupt occured by inspecting the INTR_CAUSE and SPI_STATUS registers. It then handles the interrupt by calling appropriate functions. When done, it clears the interrupt cause and SPI status registers and suspends.
function interrupt service routine do
while terminate is false do
set thread state to interruptable;
if no interrupts and synchronization state is synchronized and transmit queue is empty then
allow other tasks to run;
end if;
set thread state to busy;
check synchronization state;
if syncrhonization state is not synchronized then
flush transmit queue;
suspend for a while;
end if;
if interrupt occurred then
disable interrupts;
read interrupt cause register;
if interrupt cause is CPU on then
update synchronization state;
if synchronization state is synchronized then
continue;
end if;
end if;
if interrupt cause is packet available then
if synchronization state is synchronized then
call receive frame function;
end if;
end if;
if interrupt cause is read buffer error then
set synchronization state to unknown;
continue;
end if;
if interrupt cause is write buffer error then
set synchronization state to unknown;
continue;
end if;
clear interrupt cause register;
clear SPI status register;
end if;
if transmit queue is not empty then
call transmit frame function;
end if;
end while;
set thread state to dormant;
return;
end function;
function synchronize slave do
allocate a static reset counter;
if synchronization state is CPU on then
read QCA7000 signature register;
read QCA7000 signature register;
if signature is invalid then
set synchronization state to unknown;
else
read write buffer space available register;
if write buffer is empty then
set qca.SynchState to QCASPI_SYNC_READY;
set synchronization state to ready;
return;
else
set synchronization state to unknown;
end if;
end if;
end if;
if synchronization state is ready then
if mode is legacy then
return;
end if;
read QCA7000 signature register;
if signature is invalid then
set synchronization state to unknown;
return;
end if;
end if;
if synchronization state is unknown then
if mode is legacy then
use GPIO to reset QCA7000;
else
read QCA7000 signature register;
if signature is invalid then
return;
end if;
set soc_core_reset bit in QCA SPI configuration register;
end if;
set synchronization state to reset;
clear reset counter;
return;
end if;
if synchronization state is reset then
increment reset counter;
if reset counter exceeds reset limit then
set synchronization state to unknown;
end if;
end if;
return;
end function;
function interrupt handler do
increment interrupt count;
if thread is available and thread is dormant then
wake up thread to service interrupt;
end if;
return success;
end function;