qcaspi.txt 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. function receive frame
  2. allocate an input buffer;
  3. if no memory available then
  4. return failure;
  5. end if;
  6. read the read buffer space available register;
  7. if read buffer is empty then
  8. return an error;
  9. end if;
  10. write frame length into buffer size register;
  11. if mode is legacy then
  12. send SPI read command;
  13. end if;
  14. while read buffer is not empty do
  15. read read buffer;
  16. extract Ethernet frame from your frame buffer;
  17. update any read statistics;
  18. end while;
  19. return success;
  20. end function;
  21. function transmit frame do
  22. read the write buffer space available register;
  23. while transmit queue is not empty and write buffer space is available do
  24. encapsulate transmit frame;
  25. write transmit frame to write buffer;
  26. update transmit statistics;
  27. if error then
  28. return failure;
  29. end if;
  30. update transmit statistics;
  31. remove frame from transmit queue;
  32. end while;
  33. return success;
  34. end function;
  35. 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 <varname>INTR_CAUSE</varname> and <varname>SPI_STATUS</varname> registers. It then handles the interrupt by calling appropriate functions. When done, it clears the interrupt cause and SPI status registers and suspends.
  36. function interrupt service routine do
  37. while terminate is false do
  38. set thread state to interruptable;
  39. if no interrupts and synchronization state is synchronized and transmit queue is empty then
  40. allow other tasks to run;
  41. end if;
  42. set thread state to busy;
  43. check synchronization state;
  44. if syncrhonization state is not synchronized then
  45. flush transmit queue;
  46. suspend for a while;
  47. end if;
  48. if interrupt occurred then
  49. disable interrupts;
  50. read interrupt cause register;
  51. if interrupt cause is CPU on then
  52. update synchronization state;
  53. if synchronization state is synchronized then
  54. continue;
  55. end if;
  56. end if;
  57. if interrupt cause is packet available then
  58. if synchronization state is synchronized then
  59. call receive frame function;
  60. end if;
  61. end if;
  62. if interrupt cause is read buffer error then
  63. set synchronization state to unknown;
  64. continue;
  65. end if;
  66. if interrupt cause is write buffer error then
  67. set synchronization state to unknown;
  68. continue;
  69. end if;
  70. clear interrupt cause register;
  71. clear SPI status register;
  72. end if;
  73. if transmit queue is not empty then
  74. call transmit frame function;
  75. end if;
  76. end while;
  77. set thread state to dormant;
  78. return;
  79. end function;
  80. function synchronize slave do
  81. allocate a static reset counter;
  82. if synchronization state is CPU on then
  83. read QCA7000 signature register;
  84. read QCA7000 signature register;
  85. if signature is invalid then
  86. set synchronization state to unknown;
  87. else
  88. read write buffer space available register;
  89. if write buffer is empty then
  90. set qca.SynchState to QCASPI_SYNC_READY;
  91. set synchronization state to ready;
  92. return;
  93. else
  94. set synchronization state to unknown;
  95. end if;
  96. end if;
  97. end if;
  98. if synchronization state is ready then
  99. if mode is legacy then
  100. return;
  101. end if;
  102. read QCA7000 signature register;
  103. if signature is invalid then
  104. set synchronization state to unknown;
  105. return;
  106. end if;
  107. end if;
  108. if synchronization state is unknown then
  109. if mode is legacy then
  110. use GPIO to reset QCA7000;
  111. else
  112. read QCA7000 signature register;
  113. if signature is invalid then
  114. return;
  115. end if;
  116. set soc_core_reset bit in QCA SPI configuration register;
  117. end if;
  118. set synchronization state to reset;
  119. clear reset counter;
  120. return;
  121. end if;
  122. if synchronization state is reset then
  123. increment reset counter;
  124. if reset counter exceeds reset limit then
  125. set synchronization state to unknown;
  126. end if;
  127. end if;
  128. return;
  129. end function;
  130. function interrupt handler do
  131. increment interrupt count;
  132. if thread is available and thread is dormant then
  133. wake up thread to service interrupt;
  134. end if;
  135. return success;
  136. end function;