[processor-sdk/pdk.git] / packages / ti / drv / icss_emac / firmware / icss_dualemac / src / emac_MII_Xmt.asm
1 ;
2 ; TEXAS INSTRUMENTS TEXT FILE LICENSE
3 ;
4 ; Copyright (c) 2017-2018 Texas Instruments Incorporated
5 ;
6 ; All rights reserved not granted herein.
7 ;
8 ; Limited License.
9 ;
10 ; Texas Instruments Incorporated grants a world-wide, royalty-free, non-exclusive
11 ; license under copyrights and patents it now or hereafter owns or controls to
12 ; make, have made, use, import, offer to sell and sell ("Utilize") this software
13 ; subject to the terms herein. With respect to the foregoing patent license,
14 ; such license is granted solely to the extent that any such patent is necessary
15 ; to Utilize the software alone. The patent license shall not apply to any
16 ; combinations which include this software, other than combinations with devices
17 ; manufactured by or for TI (“TI Devices”). No hardware patent is licensed hereunder.
18 ;
19 ; Redistributions must preserve existing copyright notices and reproduce this license
20 ; (including the above copyright notice and the disclaimer and (if applicable) source
21 ; code license limitations below) in the documentation and/or other materials provided
22 ; with the distribution.
23 ;
24 ; Redistribution and use in binary form, without modification, are permitted provided
25 ; that the following conditions are met:
26 ; No reverse engineering, decompilation, or disassembly of this software is
27 ; permitted with respect to any software provided in binary form.
28 ; Any redistribution and use are licensed by TI for use only with TI Devices.
29 ; Nothing shall obligate TI to provide you with source code for the software
30 ; licensed and provided to you in object code.
31 ;
32 ; If software source code is provided to you, modification and redistribution of the
33 ; source code are permitted provided that the following conditions are met:
34 ; Any redistribution and use of the source code, including any resulting derivative
35 ; works, are licensed by TI for use only with TI Devices.
36 ; Any redistribution and use of any object code compiled from the source code
37 ; and any resulting derivative works, are licensed by TI for use only with TI Devices.
38 ;
39 ; Neither the name of Texas Instruments Incorporated nor the names of its suppliers
40 ; may be used to endorse or promote products derived from this software without
41 ; specific prior written permission.
42 ;
43 ; DISCLAIMER.
44 ;
45 ; THIS SOFTWARE IS PROVIDED BY TI AND TI’S LICENSORS "AS IS" AND ANY EXPRESS OR IMPLIED
46 ; WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
47 ; AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL TI AND TI’S
48 ; LICENSORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
49 ; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
50 ; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
51 ; CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 ; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
53 ; EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 ;
55 ; file: emac_MII_Xmt.asm
56 ;
57 ; brief: Transmit task.
58 ;
59 ;
60 ; (C) Copyright 2017-2018, Texas Instruments, Inc
61 ;
62 ;
64 .if !$defined("__mii_xmt_p")
65 __mii_xmt_p .set 1
67 ;;///////////////////////////////////////////////////////
68 ; Includes Section
69 ;;///////////////////////////////////////////////////////
70 .include "icss_intc_regs.h"
71 .if $defined("ICSS_DUAL_EMAC_BUILD")
72 .include "icss_emacSwitch.h"
73 .endif
74 .if $defined("ICSS_SWITCH_BUILD")
75 .include "icss_switch.h"
76 .endif
77 .include "icss_miirt_regs.h"
78 .include "icss_defines.h"
79 .include "micro_scheduler.h"
80 .include "emac_MII_Xmt.h"
81 .include "emac_MII_Rcv.h"
82 .include "icss_macros.h"
83 .include "emac_MII_Xmt.h"
84 .include "icss_iep_regs.h"
85 .if $defined("TTS")
86 .include "emac_tts.h"
87 .endif
89 .if $defined(PTP)
90 .include "icss_ptp.h"
91 .include "icss_ptp_macro.h"
92 .cdecls C,NOLIST
93 %{
94 #include "icss_timeSync_memory_map.h"
95 %}
96 .endif ;PTP
97 .global FN_RCV_LB
98 .global XMT_QUEUE
99 .global MII_TX_TASK
100 .global TASK_EXECUTION_FINISHED
101 .global CHECK_NEXT_QUEUE
102 .global START_XMT_QUEUE
103 .if $defined("TTS")
104 .global FN_TTS_PKT_SIZE_CHECK_ICSS_REV1
105 .global FN_TTS_PKT_SIZE_CHECK_ICSS_REV2
106 .endif
108 .if $defined(PTP)
109 .global FN_PTP_TX_ADD_DELAY
110 .endif
112 MII_TX_TASK:
113 .if $defined("ICSS_DUAL_EMAC_BUILD")
114 LDI R0.w2 , PORT_STATUS_OFFSET ; load PORT status value from DRAM
115 .if $defined("TWO_PORT_CFG")
116 LBCO &R0.w0, PRU_CROSS_DMEM, R0.w2, 1
117 .else
118 LBCO &R0.w0, PRU_DMEM_ADDR, R0.w2, 1
119 .endif
120 .endif ;ICSS_DUAL_EMAC_BUILD
121 ; if half-duplex is enabled set the half-duplex bit else clear it
122 .if $defined("HALF_DUPLEX_ENABLED")
123 QBBS SET_HALF_DUPLEX, R0, 1
124 CLR R22 , R22 , PORT_IS_HALF_DUPLEX
125 QBA CHECK_XMT_ACTIVE
126 SET_HALF_DUPLEX:
127 SET R22 , R22 , PORT_IS_HALF_DUPLEX
129 CHECK_XMT_ACTIVE:
130 .endif
131 ; if transmission is active then continue with it else check if any queue has some packet
132 QBBS XMT_QUEUE, R23, Xmt_active
134 ;****************************************************************************
135 ;
136 ; NAME : FN_XMT_scheduler
137 ; DESCRIPTION : if any queue is not empty then schedules the trasmit
138 ; RETURNS :
139 ; ARGS :
140 ; USES :
141 ; INVOKES :
142 ;
143 ;****************************************************************************
144 TX_QUEUE_CONT:
145 ;check if port link is up else jump to next task
146 .if $defined("ICSS_SWITCH_BUILD")
147 QBBS XMT_FB_EGRESS_LINK_UP_FWD, R22, 10 ;replaced: QBBS XMT_FB_EGRESS_LINK_UP_FWD, OPPOSITE_PORT_LINK_UP
148 .endif ;ICSS_SWITCH_BUILD
149 .if $defined("ICSS_DUAL_EMAC_BUILD")
150 QBBS XMT_FB_EGRESS_LINK_UP_FWD, R0, 0
151 .endif ;ICSS_DUAL_EMAC_BUILD
152 QBA NO_TRANSMIT_PACKET
154 .if $defined("HALF_DUPLEX_ENABLED")
155 COLLISION_DETECTED:
156 ;this is the collision detect procedure
157 CLR R23 , R23 , 0 ; clear the XMT_active flag indicating active transmission
159 ;reset TX FIFO
160 M_TX_RESET
162 ;Add 1 to collision counter
163 LDI R0 , COLLISION_COUNTER
164 LBCO &R2, PRU_DMEM_ADDR, R0, 1
165 ADD R2.b0, R2.b0, 1
166 SBCO &R2, PRU_DMEM_ADDR, R0, 1
168 ;clear the stat flags for TX_BC_FRAME and TX_MC_FRAME
169 CLR R22 , R22 , TX_BC_FRAME
170 CLR R22 , R22 , TX_MC_FRAME
172 ; if there is late collision then jump else continue to next task
173 QBBS ADD_TX_STATS_DO_NOT_RESET_COLLISION_COUNTER, R22 , TX_LATE_COLLISION
174 QBA NO_TRANSMIT_PACKET
176 CARRIER_SENSE_DETECTED:
177 ;this is the carrier sense procedure
178 CLR R23 , R23 , 0
179 LDI R0 , TX_DEFERRED_OFFSET
180 QBA INCREMENT_TX_COUNT
182 ADD_TX_STATS:
183 ;initialize the collision counter
184 LDI R3 , COLLISION_COUNTER
185 LDI R2.b0 , 0
186 SBCO &R2, PRU_DMEM_ADDR, R3, 1
187 QBA INCREMENT_TX_COUNT
189 ADD_TX_STATS_DO_NOT_RESET_COLLISION_COUNTER:
190 ; increment and update the late collision counter
191 CLR R22 , R22 , TX_LATE_COLLISION
192 LDI R0 , LATE_COLLISION_OFFSET
193 INCREMENT_TX_COUNT:
194 LBCO &R2, PRU_DMEM_ADDR, R0, 4
195 ADD R2, R2, 1
196 SBCO &R2, PRU_DMEM_ADDR, R0, 4
197 .endif ;HALF_DUPLEX_ENABLED
199 NO_TRANSMIT_PACKET:
200 JMP TASK_EXECUTION_FINISHED
202 XMT_FB_EGRESS_LINK_UP_FWD:
203 ; New optimized code for checking the transmit queues
204 ; Loop four times as there are four transmit queues
206 .if $defined("PRU0")
207 .if $defined("TWO_PORT_CFG")
209 LDI R20.w0, P2_Q4_TX_CONTEXT_OFFSET
210 LDI QUEUE_DESC_OFFSET, P2_QUEUE_DESC_OFFSET - 8
211 LDI TX_CONTEXT_OFFSET, P2_Q1_TX_CONTEXT_OFFSET - 8
212 CHECK_NEXT_QUEUE:
213 QBEQ NO_TRANSMIT_PACKET, TX_CONTEXT_OFFSET, R20.w0
214 ADD QUEUE_DESC_OFFSET, QUEUE_DESC_OFFSET, 8
215 LBCO &QUEUE_DESC_REG, QUEUE_DESP_BASE, QUEUE_DESC_OFFSET, 8
216 ADD TX_CONTEXT_OFFSET, TX_CONTEXT_OFFSET, 8
217 QBEQ CHECK_NEXT_QUEUE, QUEUE_DESC_REG.wr_ptr, QUEUE_DESC_REG.rd_ptr
218 .else ;MAC MODE
219 LDI R20.w0, Q4_TX_CONTEXT_OFFSET ; set R20 to last offset before it begins
220 LDI QUEUE_DESC_OFFSET , PORT_QUEUE_DESC_OFFSET - 8 ;set QUEUE_DESC_OFFSET to base before it begin
221 LDI TX_CONTEXT_OFFSET , Q1_TX_CONTEXT_OFFSET - 8 ;set TX_CONTEXT_OFFSET to base before it begin
222 CHECK_NEXT_QUEUE:
223 .if $defined("HALF_DUPLEX_ENABLED")
224 ;skip if half duplex is not set
225 QBBC SKIP_CRS_Q, R22 , PORT_IS_HALF_DUPLEX
226 ;defer if carrier sense is on via reading the PRUSS_MII_RT_PRS0 register
227 LBCO &TEMP_REG_1, MII_RT_CFG_CONST, MII_CARRIER_SENSE_REG, 1
228 QBBS CARRIER_SENSE_DETECTED, TEMP_REG_1, 1
229 SKIP_CRS_Q:
230 .endif ;HALF_DUPLEX_ENABLED
231 QBEQ NO_TRANSMIT_PACKET, TX_CONTEXT_OFFSET, R20.w0 ; if TX_CONTEXT_OFFSET matches the last descriptor then nothing to transmit
232 ADD QUEUE_DESC_OFFSET, QUEUE_DESC_OFFSET, 8
233 LBCO &QUEUE_DESC_REG, PRU_DMEM_ADDR, QUEUE_DESC_OFFSET, 8
234 ADD TX_CONTEXT_OFFSET, TX_CONTEXT_OFFSET, 8 ; increment the queue and buffer offset
235 QBEQ CHECK_NEXT_QUEUE, QUEUE_DESC_REG.wr_ptr, QUEUE_DESC_REG.rd_ptr ; if read == write pointer then move to next queue
236 .if $defined("TTS")
237 M_TTS_XMT_SCHEDULER TX_CONTEXT_OFFSET ; check if queue has any TTS packets
238 .endif ;TTS
239 .endif
240 .else
241 ;PRU1
242 .if $defined("TWO_PORT_CFG")
244 LDI R20.w0, P1_Q4_TX_CONTEXT_OFFSET
245 LDI QUEUE_DESC_OFFSET, P1_QUEUE_DESC_OFFSET - 8
246 LDI TX_CONTEXT_OFFSET, P1_Q1_TX_CONTEXT_OFFSET - 8
247 CHECK_NEXT_QUEUE:
248 QBEQ NO_TRANSMIT_PACKET, TX_CONTEXT_OFFSET, R20.w0
249 ADD QUEUE_DESC_OFFSET, QUEUE_DESC_OFFSET, 8
250 LBCO &QUEUE_DESC_REG, QUEUE_DESP_BASE, QUEUE_DESC_OFFSET, 8
251 ADD TX_CONTEXT_OFFSET, TX_CONTEXT_OFFSET, 8
252 QBEQ CHECK_NEXT_QUEUE, QUEUE_DESC_REG.wr_ptr, QUEUE_DESC_REG.rd_ptr
253 .else ;MAC MODE
254 LDI R20.w0, Q4_TX_CONTEXT_OFFSET ; set R20 to last offset before it begins
255 LDI QUEUE_DESC_OFFSET , PORT_QUEUE_DESC_OFFSET - 8 ;set QUEUE_DESC_OFFSET to base before it begin
256 LDI TX_CONTEXT_OFFSET , Q1_TX_CONTEXT_OFFSET - 8 ;set TX_CONTEXT_OFFSET to base before it begin
257 CHECK_NEXT_QUEUE:
258 .if $defined("HALF_DUPLEX_ENABLED")
259 ;skip if half duplex is not set
260 QBBC SKIP_CRS_Q, R22 , PORT_IS_HALF_DUPLEX
261 ;defer if carrier sense is on via reading the PRUSS_MII_RT_PRS1 register
262 LBCO &TEMP_REG_1, MII_RT_CFG_CONST, MII_CARRIER_SENSE_REG, 1
263 QBBS CARRIER_SENSE_DETECTED, TEMP_REG_1, 1
264 SKIP_CRS_Q:
265 .endif ;HALF_DUPLEX_ENABLED
266 QBEQ NO_TRANSMIT_PACKET, TX_CONTEXT_OFFSET, R20.w0 ; if TX_CONTEXT_OFFSET matches the last descriptor then nothing to transmit
267 ADD QUEUE_DESC_OFFSET, QUEUE_DESC_OFFSET, 8
268 LBCO &QUEUE_DESC_REG, PRU_DMEM_ADDR, QUEUE_DESC_OFFSET, 8
269 ADD TX_CONTEXT_OFFSET, TX_CONTEXT_OFFSET, 8 ; increment the queue and buffer offset
270 QBEQ CHECK_NEXT_QUEUE, QUEUE_DESC_REG.wr_ptr, QUEUE_DESC_REG.rd_ptr ; if read == write pointer then move to next queue
271 .if $defined("TTS")
272 M_TTS_XMT_SCHEDULER TX_CONTEXT_OFFSET ; check if queue has any TTS packets
273 .endif ;TTS
274 .endif
275 .endif
277 ;;////////////////////////////////////////////////////////////////////////////////////////
279 ;****************************************************************************
280 ;
281 ; NAME : FN_XMT_queue
282 ; DESCRIPTION : trasmits the first block of 32B data from the queue into TX FIFO
283 ; RETURNS :
284 ; ARGS :
285 ; USES :
286 ; INVOKES :
287 ;
288 ;****************************************************************************
289 START_XMT_QUEUE:
290 ; Read the TX Context of 8 Bytes.
291 .if $defined("TWO_PORT_CFG")
292 LBCO &BUFFER_OFFSET, PRU1_DMEM_CONST, TX_CONTEXT_OFFSET, 8
293 .else
294 LBCO &BUFFER_OFFSET, PRU_DMEM_ADDR, TX_CONTEXT_OFFSET, 8
295 .endif ;TWO_PORT_CFG
296 ; init MII_XMT parameter
297 SET R23 , R23 , Xmt_active ; set global flag to indicate an ongoing transmission
298 SUB BUFFER_DESC_OFFSET, QUEUE_DESC_REG.rd_ptr, BASE_BUFFER_DESC_OFFSET ;subtract the rd-ptr value from base
299 LSL BUFFER_DESC_OFFSET, BUFFER_DESC_OFFSET, 3 ; shift the value by 3 as descriptor size is 8 bytes
300 ADD BUFFER_INDEX, BUFFER_OFFSET, BUFFER_DESC_OFFSET ; find the actual buffer index.
301 AND BUFFER_DESC_OFFSET , QUEUE_DESC_REG.rd_ptr , QUEUE_DESC_REG.rd_ptr
302 .if $defined("TWO_PORT_CFG")
303 LBCO &BUFFER_DESC_REG, ICSS_SHARED_CONST, BUFFER_DESC_OFFSET, 4
304 .else
305 LBCO &BUFFER_DESC_REG, PRU_DMEM_ADDR, BUFFER_DESC_OFFSET, 4 ; load the buffer_desc_reg form offset
306 .endif ;TWO_PORT_CFG
307 LSL Packet_Length, BUFFER_DESC_REG.pkt_length, 3 ;bit 18...28
309 LSR Packet_Length, Packet_Length, 5
310 LDI BYTE_CNT , 0
311 ; Read the Phy speed and set the flag accordingly
312 LDI R2.w0, PHY_SPEED_OFFSET
313 .if $defined("TWO_PORT_CFG")
314 LBCO &R2.w2, PRU_CROSS_DMEM , R2.w0, 2
315 .else
316 LBCO &R2.w2, PRU_DMEM_ADDR, R2.w0, 2
317 .endif
319 SET R23 , R23 , TX_PHY_SPEED ; means PHY is set to 100 Mbps
320 QBEQ XMT_FB_100Mbps_MODE, R2.b2, 100
321 CLR R23 , R23 , TX_PHY_SPEED ; means PHY is set to 10 Mbps
322 XMT_FB_100Mbps_MODE:
323 .if $defined("TWO_PORT_CFG")
324 CLR R13, R13, PACKET_FROM_COLL_QUEUE
325 QBBC no_collision_occured, R11, 14 ;BUFFER_DESC_REG.Shadow ;BUFFER_DESC_REG.Shadow
326 SET R13, R13, PACKET_FROM_COLL_QUEUE
327 ; Change the Precompute offsets to one's for the collision buffer
328 .if $defined("PRU0")
329 LDI TX_CONTEXT_OFFSET, COL_TX_CONTEXT_P2_Q1_OFFSET_ADDR
330 .else
331 LDI TX_CONTEXT_OFFSET, COL_TX_CONTEXT_P1_Q1_OFFSET_ADDR
332 .endif
333 ; Read the Collision TX Context of 6 Bytes.
334 LBCO &BUFFER_INDEX, PRU1_DMEM_CONST, TX_CONTEXT_OFFSET, 6
335 no_collision_occured:
336 .endif ;TWO_PORT_CFG
337 CHECK_RX_EOF:
338 ;Check RX EOF.
339 .if $defined("ICSS_REV1")
340 M_XMT_RX_EOF_CHECK_ICSS_REV1 process_rx_eof_tx_fb ; check EOF of RCV is receive is active
341 .endif
342 .if $defined("ICSS_REV2")
343 M_XMT_RX_EOF_CHECK_ICSS_REV2 process_rx_eof_tx_fb ; check EOF of RCV is receive is active
344 .endif
346 LBCO &BUFFER, L3_OCMC_RAM_CONST, BUFFER_INDEX, 32 ; load the buffer value from its index
347 .if $defined("HALF_DUPLEX_ENABLED")
348 ;load the value of PRUSS_MII_RT_PRS0 register and check for carrier sense
349 QBBC CONTINUE_TX, R22 , PORT_IS_HALF_DUPLEX
350 LBCO &R0, MII_RT_CFG_CONST, MII_CARRIER_SENSE_REG, 1
351 QBBC CONTINUE_TX, R0, 1
352 QBA CARRIER_SENSE_DETECTED
354 CONTINUE_TX:
355 .endif ;HALF_DUPLEX_ENABLED
357 ;Do TX stats here
358 QBBS TX_IS_MC_OR_BC, R2, 0
359 QBA START_TX_FIFO_FILL
361 TX_IS_MC_OR_BC:
362 ; based on mac address find out if it BC or MC frame
363 FILL &R0, 4 ;Fill with 0xffffffff
364 QBNE TX_IS_MC, R2, R0 ;First four bytes of MAC ID
365 QBNE TX_IS_MC, R3.w0, R0.w0 ;upper two bytes of MAC ID
366 SET R22 , R22 , TX_BC_FRAME
367 QBA START_TX_FIFO_FILL
369 TX_IS_MC:
370 SET R22 , R22 , TX_MC_FRAME
372 START_TX_FIFO_FILL:
373 .if $defined("TTS")
374 M_TTS_TX_SOF_PREV_STORE
375 .endif ;TTS
377 .if $defined("ICSS_REV1")
378 ;Just before pushing to FIFO store the current Tx SOF TS
379 ;This is used for comparison later to make sure SOF has actually
380 ;updated
381 .if $defined (PTP)
382 .if $defined("ICSS_SWITCH_BUILD")
383 .if $defined (PRU0)
384 LBCO &R20, ICSS_IEP_CONST, CAP_RISE_TX_SOF_PORT2_OFFSET, 4
385 LDI RCV_TEMP_REG_2, PTP_PREV_TX_TIMESTAMP_P2
386 SBCO &R20, ICSS_SHARED_CONST, RCV_TEMP_REG_2, 4
387 ;SBCO &R20, ICSS_SHARED_CONST, PTP_PREV_TX_TIMESTAMP_P2, 4
388 .else
389 LBCO &R20, ICSS_IEP_CONST, CAP_RISE_TX_SOF_PORT1_OFFSET, 4
390 ;LDI RCV_TEMP_REG_1, PTP_PREV_TX_TIMESTAMP_P1
391 ;SBCO &R20, ICSS_SHARED_CONST, RCV_TEMP_REG_1, 4
392 SBCO &R20, ICSS_SHARED_CONST, PTP_PREV_TX_TIMESTAMP_P1, 4
393 .endif
394 .else
395 .if $defined (PRU0)
396 LBCO &R20, IEP_CONST, CAP_RISE_TX_SOF_PORT1_OFFSET, 4
397 LDI RCV_TEMP_REG_2, PTP_PREV_TX_TIMESTAMP_P1
398 SBCO &R20, ICSS_SHARED_CONST, RCV_TEMP_REG_2, 4
399 ;SBCO &R20, ICSS_SHARED_CONST, PTP_PREV_TX_TIMESTAMP_P1, 4
400 .else
401 LBCO &R20, IEP_CONST, CAP_RISE_TX_SOF_PORT2_OFFSET, 4
402 LDI RCV_TEMP_REG_1, PTP_PREV_TX_TIMESTAMP_P2
403 SBCO &R20, ICSS_SHARED_CONST, RCV_TEMP_REG_1, 4
404 ;SBCO &R20, ICSS_SHARED_CONST, PTP_PREV_TX_TIMESTAMP_P2, 4
405 .endif
406 .endif ; ICSS_SWITCH_BUILD
407 .endif ;PTP
408 LDI TX_DATA_WORD_MASK , 0xffff
409 AND TX_DATA_BYTE , BUFFER.b0 , BUFFER.b0
410 M_PUSH_BYTE
411 AND TX_DATA_BYTE , BUFFER.b1 , BUFFER.b1
412 M_PUSH_BYTE
413 .endif ;ICSS_REV1
415 PUSH_FB:
416 .if $defined (PTP)
417 M_GPTP_TX_PRE_PROC
418 .endif ;PTP
419 ; Insert the data in Tx Fifo
420 .if $defined("ICSS_REV1")
421 LDI TX_DATA_POINTER, buffer_ptr + 2
422 loop EndLoop_FB1, 15 ; Insert 32 bytes for ICSS_REV1
423 MVIW TX_DATA_WORD, *TX_DATA_POINTER
424 M_PUSH_WORD_CMD
425 ADD TX_DATA_POINTER, TX_DATA_POINTER, 2
426 EndLoop_FB1:
427 .endif ;ICSS_REV1
429 .if $defined("ICSS_REV2")
430 LDI TX_DATA_POINTER, buffer_ptr
431 loop EndLoop_FB1, 8 ; Insert 32 bytes for ICSS_REV2
432 MVID TX_DATA_DOUBLE_WORD, *TX_DATA_POINTER
433 ADD TX_DATA_POINTER, TX_DATA_POINTER, 4
434 EndLoop_FB1:
435 .endif ;ICSS_REV2
436 ;For EMAC we don't do bridge delay correction
437 ;So this can be called after pushing 32 bytes
438 .if $defined (PTP)
439 JAL R0.w0, FN_PTP_TX_ADD_DELAY
440 .endif
442 ;increment both descriptor and index with offset
443 ADD BUFFER_INDEX, BUFFER_INDEX, 32
444 ADD BYTE_CNT, BYTE_CNT, 32
445 SET R13 , R13 , INCREMENT_WRK_BUFFER_DESC_OFFSET
446 LDI BYTES_TRANSFERRED_IN_LAST_CALL, 0x00 ; indicate how many bytes have been transfered in last call
447 LDI SHIFT_REG, SHIFT_NONE
448 ; store the context back
449 .if $defined("PRU0")
450 XOUT BANK1, &MII_TX_CONTEXT, 20
451 .else
452 XOUT BANK2, &MII_TX_CONTEXT, 20
453 .endif
455 .if $defined("HALF_DUPLEX_ENABLED")
456 ;load the value of PRUSS_MII_RT_PRS0 register and check for carrier sense
457 QBBC NO_COLLISION1, R22 , PORT_IS_HALF_DUPLEX
458 LBCO &TEMP_REG_1, MII_RT_CFG_CONST, MII_CARRIER_SENSE_REG, 1
459 QBBC NO_COLLISION1, TEMP_REG_1, 0
460 QBA COLLISION_DETECTED
461 NO_COLLISION1:
462 .endif ;HALF_DUPLEX_ENABLED
464 .if $defined("ICSS_REV1")
465 M_XMT_RX_EOF_CHECK_ICSS_REV1 process_rx_eof_tx_fb_after_inserting_32bytes ;check for EOF for recieve buffer if recieve is active
466 .endif ;ICSS_REV1
467 .if $defined("ICSS_REV2")
468 M_XMT_RX_EOF_CHECK_ICSS_REV2 process_rx_eof_tx_fb_after_inserting_32bytes ;check for EOF for recieve buffer if recieve is active
469 .endif ;ICSS_REV2
471 ; No RX EOF event so fill Tx FIFO more bytes
472 QBNE NO_QUEUE_WRAP_XMT_FB, BUFFER_DESC_OFFSET, TOP_MOST_BUFFER_DESC_OFFSET
473 AND BUFFER_DESC_OFFSET , BASE_BUFFER_DESC_OFFSET , BASE_BUFFER_DESC_OFFSET
474 CLR R13 , R13 , INCREMENT_WRK_BUFFER_DESC_OFFSET ; Since the Queue has wrapped here itself ..no need to check for it in xmt_nb for first time
475 .if $defined("TWO_PORT_CFG")
476 QBBS NO_QUEUE_WRAP_XMT_FB, R13, 2 ;PACKET_FROM_COLL_QUEUE
477 .endif ;TWO_PORT_CFG
478 AND BUFFER_INDEX , BUFFER_OFFSET , BUFFER_OFFSET
480 NO_QUEUE_WRAP_XMT_FB:
482 LBCO &BUFFER, L3_OCMC_RAM_CONST, BUFFER_INDEX, 32 ; load new data from buffer
483 LDI TX_DATA_POINTER, buffer_ptr
485 .if $defined("ICSS_REV1")
486 ; Insert next 22 bytes in Tx FIFO
487 loop EndLoop_FB_22bytes_more, 11
488 MVIW TX_DATA_WORD, *TX_DATA_POINTER
489 M_PUSH_WORD_CMD
490 ADD TX_DATA_POINTER, TX_DATA_POINTER, 2
491 EndLoop_FB_22bytes_more:
492 ; increment the buffer and byte count
493 ADD BUFFER_INDEX, BUFFER_INDEX, 22
494 ADD BYTE_CNT, BYTE_CNT, 22
495 LDI BYTES_TRANSFERRED_IN_LAST_CALL, 22
496 LDI SHIFT_REG, SHIFT_NONE
497 .endif ;ICSS_REV1
499 .if $defined("ICSS_REV2")
500 ; Insert next 28 bytes in Tx FIFO
501 loop EndLoop_FB_28bytes_more, 7
502 MVID TX_DATA_DOUBLE_WORD, *TX_DATA_POINTER
503 ADD TX_DATA_POINTER, TX_DATA_POINTER, 4
504 EndLoop_FB_28bytes_more:
505 ;increment the buffer and byte count
506 ADD BUFFER_INDEX, BUFFER_INDEX, 28
507 ADD BYTE_CNT, BYTE_CNT, 28
508 LDI BYTES_TRANSFERRED_IN_LAST_CALL, 28
509 LDI SHIFT_REG, SHIFT_NONE
510 .endif ;ICSS_REV2
512 ; store the context back
513 .if $defined("PRU0")
514 XOUT BANK1, &MII_TX_CONTEXT, 20
515 .else
516 XOUT BANK2, &MII_TX_CONTEXT, 20
517 .endif
518 .if $defined("HALF_DUPLEX_ENABLED")
519 ;load the value of PRUSS_MII_RT_PRS0 register and check for carrier sense
520 QBBC NO_COLLISION2, R22 , PORT_IS_HALF_DUPLEX
521 LBCO &TEMP_REG_1, MII_RT_CFG_CONST, MII_CARRIER_SENSE_REG, 1
522 QBBC NO_COLLISION2, TEMP_REG_1, 0
523 QBA COLLISION_DETECTED
524 NO_COLLISION2:
525 .endif ;HALF_DUPLEX_ENABLED
527 TASK_EXECUTION_FINISHED_intr:
528 JMP TASK_EXECUTION_FINISHED
530 process_rx_eof_tx_fb:
531 CLR R23 , R23 , Xmt_active
532 process_rx_eof_tx_fb_after_inserting_32bytes:
533 JAL CALL_REG, FN_RCV_LB ; jump to transmit last 32 bytes
535 ;****************************************************************************
536 ;
537 ; NAME : XMT_QUEUE
538 ; DESCRIPTION : trasmits the next block of 32B data from the queue into TX FIFO
539 ; RETURNS :
540 ; ARGS :
541 ; USES :
542 ; INVOKES :
543 ;
544 ;****************************************************************************
545 XMT_QUEUE:
546 .if $defined("ICSS_DUAL_EMAC_BUILD")
547 ;check if port link is up else move to next task
548 LDI R0.w2 , PORT_STATUS_OFFSET
549 LBCO &R0.b0, PRU_DMEM_ADDR, R0.w2, 1
550 QBBS XMT_QUEUE_PORT_LINK_IS_UP, R0, 0
551 ;Port link has gone down while frame was in transmission.
552 CLR R23 , R23 , 0
553 M_TX_RESET
554 SET R22 , R22 , PACKET_TX_ALLOWED
555 JMP TASK_EXECUTION_FINISHED
556 XMT_QUEUE_PORT_LINK_IS_UP:
557 .endif ;ICSS_DUAL_EMAC_BUILD
558 ; load the content of tx context back from the banks
559 LDI SHIFT_REG, SHIFT_NONE
560 .if $defined("PRU0")
561 XIN BANK1, &MII_TX_CONTEXT, 20
562 .else
563 XIN BANK2, &MII_TX_CONTEXT, 20
564 .endif
566 ; check and set if half duplex is set
567 .if $defined("HALF_DUPLEX_ENABLED")
568 LDI TEMP_REG_3.w2 , PORT_STATUS_OFFSET
569 LBCO &TEMP_REG_3.w0, ICSS_SHARED_CONST, TEMP_REG_3.w2, 1
570 QBBS SET_HALF_DUPLEX1, TEMP_REG_3, 0
571 CLR R22 , R22 , PORT_IS_HALF_DUPLEX
572 QBA CONTINUE_XMT_QUEUE
573 SET_HALF_DUPLEX1:
574 SET R22 , R22 , PORT_IS_HALF_DUPLEX
575 .endif ;HALF_DUPLEX_ENABLED
577 CONTINUE_XMT_QUEUE:
579 .if $defined("TTS")
580 M_TTS_FIFO_FILL_MOD ;find the current fifo fill level based on compare event
581 .endif ;TTS
583 .if $defined("ICSS_DUAL_EMAC_BUILD")
584 .if !$defined("TTS")
585 ;Only need to read in non-TTS EMAC.
586 ;For TTS EMAC, it is read in M_TTS_FIFO_FILL_MOD-->M_TTS_TX_SOF_COMPARE_ICSS_REV1.
587 .if $defined("ICSS_REV1")
588 M_XMT_GET_TXSOF_ICSS_REV1
589 .endif ;ICSS_REV1
590 .endif ;TTS
591 .endif ;ICSS_DUAL_EMAC_BUILD
593 ; port tx sof capture for port 1 (PRU1) and port 2 (PRU0) - 2 port config.
594 .if $defined("TWO_PORT_CFG")
595 .if $defined("PRU0")
596 LBCO &TEMP_REG_3, IEP_CONST, CAP_RISE_TX_SOF_PORT2_OFFSET, 4
597 .else
598 LBCO &TEMP_REG_3, IEP_CONST, CAP_RISE_TX_SOF_PORT1_OFFSET, 4
599 .endif
600 .endif ;TWO_PORT_CFG
601 .if $defined("HALF_DUPLEX_ENABLED")
602 ;load the value of PRUSS_MII_RT_PRS0 register and check for carrier sense
603 QBBC NO_COLLISION3, R22 , PORT_IS_HALF_DUPLEX
604 LBCO &TEMP_REG_1, MII_RT_CFG_CONST, MII_CARRIER_SENSE_REG, 1
605 QBBC NO_COLLISION3, TEMP_REG_1, 0
606 QBA COLLISION_DETECTED
607 NO_COLLISION3:
608 .endif ;HALF_DUPLEX_ENABLED
610 .if $defined("ICSS_REV1")
611 M_XMT_FILL_LEVEL_CALC_ICSS_REV1 ; calculate the current TX fifo fill level
612 .endif ;ICSS_REV1
614 .if $defined("ICSS_REV2")
615 M_XMT_FILL_LEVEL_CALC_ICSS_REV2 ; calculate the current TX fifo fill level
616 .endif ;ICSS_REV2
618 QBEQ XMT_NB_DONE, FREE_SPACE_IN_FIFO, 0
619 QBGE FILL_TX_FIFO, FREE_SPACE_IN_FIFO, 32 ; if free space in fifo is less than 32 bytes then jmp else continue
620 LDI FREE_SPACE_IN_FIFO, 32
622 FILL_TX_FIFO:
623 ;Check for RX EOF.
624 .if $defined("ICSS_REV1")
625 M_XMT_RX_EOF_CHECK_ICSS_REV1 process_rx_eof_tx_nb ;check for EOF for recieve buffer if recieve is active
626 .endif ;ICSS_REV1
627 .if $defined("ICSS_REV2")
628 M_XMT_RX_EOF_CHECK_ICSS_REV2 process_rx_eof_tx_nb ;check for EOF for recieve buffer if recieve is active
629 .endif ;ICSS_REV2
631 QBBC QUEUE_WRAP_XMT, R13, 1 ;check if buffer increment flag is cleared
632 ; if buffer descriptor == top most buffer descriptor than set it to base value else increment it
633 QBNE NO_QUEUE_WRAP_XMT, BUFFER_DESC_OFFSET, TOP_MOST_BUFFER_DESC_OFFSET
634 AND BUFFER_DESC_OFFSET , BASE_BUFFER_DESC_OFFSET , BASE_BUFFER_DESC_OFFSET
635 CLR R13 , R13 , INCREMENT_WRK_BUFFER_DESC_OFFSET
636 .if $defined("TWO_PORT_CFG")
637 QBBS QUEUE_WRAP_XMT, R13, PACKET_FROM_COLL_QUEUE ;PACKET_FROM_COLL_QUEUE
638 .endif ;TWO_PORT_CFG
639 AND BUFFER_INDEX , BUFFER_OFFSET , BUFFER_OFFSET
640 JMP QUEUE_WRAP_XMT
642 NO_QUEUE_WRAP_XMT:
643 ADD BUFFER_DESC_OFFSET, BUFFER_DESC_OFFSET, 4 ; working rd_ptr
644 CLR R13 , R13 , INCREMENT_WRK_BUFFER_DESC_OFFSET
645 QUEUE_WRAP_XMT:
646 SUB block_size, Packet_Length, BYTE_CNT ;find out how many bytes are left
647 QBLT PUSH_NB, block_size, 32
648 LDI SHIFT_REG, SHIFT_NONE
649 .if $defined("PRU0")
650 XOUT BANK1, &MII_TX_CONTEXT, 20
651 .else
652 XOUT BANK2, &MII_TX_CONTEXT, 20
653 .endif
654 JMP XMT_LB
656 PUSH_NB:
658 ; Check whether BUFFER_INDEX is pointing to the top desc in TX Queue
659 QBLE fetch_data_from_ocmc, TOP_MOST_BUFFER_INDEX, BUFFER_INDEX
660 ; Subtract the bytes which have been already transmitted
661 SUB TEMP_REG_3.b0, BUFFER_INDEX, TOP_MOST_BUFFER_INDEX
662 RSB TEMP_REG_3.b1, TEMP_REG_3.b0, 32
663 QBLE enough_data_in_top_block, TEMP_REG_3.b1, FREE_SPACE_IN_FIFO ;if space is less than bytes to be sent than jump else continue
664 AND FREE_SPACE_IN_FIFO , TEMP_REG_3.b1 , TEMP_REG_3.b1
665 enough_data_in_top_block:
666 fetch_data_from_ocmc:
668 ; Check if the RX EOF has come
669 LBCO &BUFFER, L3_OCMC_RAM_CONST, BUFFER_INDEX, 32 ;load new buffer data
671 ; Insert Tx Data in the Tx Fifo
672 LDI TX_DATA_POINTER, buffer_ptr
673 .if $defined("ICSS_REV1")
674 ; push free_space_fifo bytes more and update the flags
675 QBEQ PUSH_ONE_BYTE, FREE_SPACE_IN_FIFO, 1
676 LSR loop_cnt, FREE_SPACE_IN_FIFO, 1
677 LOOP EndLoop_NB, loop_cnt
678 MVIW TX_DATA_WORD, *TX_DATA_POINTER
679 M_PUSH_WORD_CMD
680 ADD TX_DATA_POINTER, TX_DATA_POINTER, 2
681 EndLoop_NB:
682 .endif ;ICSS_REV1
684 .if $defined("ICSS_REV2")
685 ; push free_space_fifo bytes more and update the flags
686 LSR loop_cnt, FREE_SPACE_IN_FIFO, 2 ;divide by 4
687 LOOP EndLoop_NB, loop_cnt
688 MVID TX_DATA_DOUBLE_WORD, *TX_DATA_POINTER
689 ADD TX_DATA_POINTER, TX_DATA_POINTER, 4
690 EndLoop_NB:
691 .endif ;ICSS_REV2
693 .if $defined("HALF_DUPLEX_ENABLED")
694 ;load the value of PRUSS_MII_RT_PRS0 register and check for carrier sense
695 QBBC NO_COLLISION4, R22 , PORT_IS_HALF_DUPLEX
696 LBCO &TEMP_REG_1, MII_RT_CFG_CONST, MII_CARRIER_SENSE_REG, 1
697 QBBC NO_COLLISION4, TEMP_REG_1, 0
698 QBA COLLISION_DETECTED
699 NO_COLLISION4:
700 .endif ;HALF_DUPLEX_ENABLED
702 ;Check if any bytes are left to be added to TX FIFO.
703 .if $defined("ICSS_REV1")
704 QBBC FIFO_INSERTION_OVER, FREE_SPACE_IN_FIFO, 0
705 PUSH_ONE_BYTE:
706 MVIB TX_DATA_BYTE, *TX_DATA_POINTER
707 M_PUSH_BYTE ;write 1 byte in output fifo
708 .endif ;ICSS_REV1
710 .if $defined("ICSS_REV2")
711 AND R20.b0, FREE_SPACE_IN_FIFO, 0x03 ; Pick only last two bits
712 QBEQ FIFO_INSERTION_OVER, R20.b0, 0
713 QBEQ PUSH_ONE_BYTE, R20.b0, 1
714 MVIW TX_DATA_WORD, *TX_DATA_POINTER
715 ADD TX_DATA_POINTER, TX_DATA_POINTER, 2
716 QBEQ FIFO_INSERTION_OVER, R20.b0, 2
717 PUSH_ONE_BYTE:
718 ;check how many bytes left and fill in the rest of the bytes based on what is left
719 MVIB TX_DATA_BYTE, *TX_DATA_POINTER
720 .endif ;ICSS_REV2
722 FIFO_INSERTION_OVER:
723 ;check if bytes transferred in last call was more than 32 bytes or not
724 ;and based on it increment the byte count or move to next descriptor
725 ADD BYTES_TRANSFERRED_IN_LAST_CALL, BYTES_TRANSFERRED_IN_LAST_CALL, FREE_SPACE_IN_FIFO
726 QBGT DO_NOT_INCREMENT_BUFFER_DESC_OFFSET, BYTES_TRANSFERRED_IN_LAST_CALL, 32
727 SET R13 , R13 , INCREMENT_WRK_BUFFER_DESC_OFFSET
728 SUB BYTES_TRANSFERRED_IN_LAST_CALL, BYTES_TRANSFERRED_IN_LAST_CALL, 32
729 DO_NOT_INCREMENT_BUFFER_DESC_OFFSET:
730 ADD BUFFER_INDEX, BUFFER_INDEX, FREE_SPACE_IN_FIFO
731 ADD BYTE_CNT, BYTE_CNT, FREE_SPACE_IN_FIFO
733 LDI SHIFT_REG, SHIFT_NONE
734 ;store back value in the bank
735 .if $defined("PRU0")
736 XOUT BANK1, &MII_TX_CONTEXT, 20
737 .else
738 XOUT BANK2, &MII_TX_CONTEXT, 20
739 .endif
740 XMT_NB_DONE:
741 JMP TASK_EXECUTION_FINISHED
742 process_rx_eof_tx_nb:
743 JAL CALL_REG, FN_RCV_LB
745 error_in_fill_level:
746 ;if some error occurred than halt the code else reset tx and continue
747 .if $defined("DEBUG")
748 HALT
749 .else
750 ;This is debug code, flow doesn't come here if there is no error.
751 M_TX_RESET ;Reset the Tx Fifo
752 CLR R23 , R23 , 0 ; clear global flag to indicate the completion of transmission
753 JMP TASK_EXECUTION_FINISHED
754 .endif
756 ;****************************************************************************
757 ;
758 ; NAME : FN_XMT_LB
759 ; DESCRIPTION : transmit the last block of data from the frame in TX FIFO
760 ; RETURNS :
761 ; ARGS :
762 ; USES :
763 ; INVOKES :
764 ;
765 ;****************************************************************************
766 XMT_LB:
767 ;check the number of bytes left to send, if none left than exit.
768 ;If Free space is less than current byte count then jump to next procedure
769 SUB size, Packet_Length, BYTE_CNT
770 QBEQ XMT_OVER, size, 0
771 ADD R11.b0, size, 4
772 QBGE PUSH_LB_FIFO, R11.b0, FREE_SPACE_IN_FIFO
773 SET R22 , R22 , Entire_Tx_Data_Not_Pushed
774 QBGE PUSH_LB_FIFO, size, FREE_SPACE_IN_FIFO
775 AND size , FREE_SPACE_IN_FIFO , FREE_SPACE_IN_FIFO
776 PUSH_LB_FIFO:
777 ; Check whether BUFFER_INDEX is pointing to the top desc in TX Queue
778 QBLE fetch_data_from_ocmc_lb, TOP_MOST_BUFFER_INDEX, BUFFER_INDEX
779 ; Subtract the bytes which have been already transmitted
780 SUB TEMP_REG_3.b0, BUFFER_INDEX, TOP_MOST_BUFFER_INDEX
781 RSB TEMP_REG_3.b1, TEMP_REG_3.b0, 32
782 QBLE enough_data_in_top_block_lb, TEMP_REG_3.b1, size
783 AND size , TEMP_REG_3.b1 , TEMP_REG_3.b1
784 enough_data_in_top_block_lb:
785 fetch_data_from_ocmc_lb:
787 .if $defined("HALF_DUPLEX_ENABLED")
788 ;load the value of PRUSS_MII_RT_PRS0 register and check for carrier sense.
789 ;In these scenerio this will be late collision
790 QBBC NO_COLLISION5, R22 , PORT_IS_HALF_DUPLEX
791 LBCO &TEMP_REG_1, MII_RT_CFG_CONST, MII_CARRIER_SENSE_REG, 1
792 QBBC NO_COLLISION5, TEMP_REG_1, 0
793 SET R22 , R22 , TX_LATE_COLLISION
794 QBA COLLISION_DETECTED
795 NO_COLLISION5:
796 .endif ;HALF_DUPLEX_ENABLED
798 ; Check if the RX EOF has come
799 .if $defined("ICSS_REV1")
800 M_XMT_RX_EOF_CHECK_ICSS_REV1 process_rx_eof_tx_lb
801 .endif ;ICSS_REV1
802 .if $defined("ICSS_REV2")
803 M_XMT_RX_EOF_CHECK_ICSS_REV2 process_rx_eof_tx_lb
804 .endif ;ICSS_REV2
806 AND R0.b0 , size , size
807 LBCO &BUFFER, L3_OCMC_RAM_CONST, BUFFER_INDEX, b0 ;load the new amount of data which can be sent to Tx fifo
809 .if $defined("ICSS_REV1")
810 LDI TX_DATA_POINTER, buffer_ptr
811 QBEQ PUSH_LB_LASTBYTE, size, 1 ;if only 1 bytes check to next procedure
812 LSR loop_cnt, size, 1
813 LOOP EndLoop_LB, loop_cnt
814 MVIW TX_DATA_WORD, *TX_DATA_POINTER
815 M_PUSH_WORD_CMD
816 ADD TX_DATA_POINTER, TX_DATA_POINTER, 2 ;push free_space_fifo bytes more and update the flags
817 EndLoop_LB:
818 QBBC LB_OVER, size, 0
819 PUSH_LB_LASTBYTE:
820 MVIB TX_DATA_BYTE, *TX_DATA_POINTER ;write the final byte in the tx fifo
821 M_PUSH_BYTE
822 .endif ;ICSS_REV1
824 .if $defined("ICSS_REV2")
825 LDI TX_DATA_POINTER, buffer_ptr
826 LSR loop_cnt, size, 2 ;divide by 4
827 LOOP EndLoop_LB, loop_cnt
828 MVID TX_DATA_DOUBLE_WORD, *TX_DATA_POINTER
829 ADD TX_DATA_POINTER, TX_DATA_POINTER, 4 ;push free_space_fifo bytes more and update the flags
830 EndLoop_LB:
831 AND R20.b0, size, 0x03 ; Pick only last two bits
832 QBEQ LB_OVER, R20.b0, 0
833 QBEQ PUSH_LB_LASTBYTE, R20.b0, 1
834 MVIW TX_DATA_WORD, *TX_DATA_POINTER
835 ADD TX_DATA_POINTER, TX_DATA_POINTER, 2
836 QBEQ LB_OVER, R20.b0, 2 ;check how many bytes left and fill in the rest of the bytes based on what is left
837 PUSH_LB_LASTBYTE:
838 MVIB TX_DATA_BYTE, *TX_DATA_POINTER
839 .endif ;ICSS_REV2
841 LB_OVER:
842 ;check the number of bytes left to send, if none left than exit.
843 ;If Free space is less than current byte count then jump to next procedure
844 ADD BYTE_CNT, BYTE_CNT, size
845 SUB FREE_SPACE_IN_FIFO, FREE_SPACE_IN_FIFO, size
846 ADD BUFFER_INDEX, BUFFER_INDEX, size
847 ADD BYTES_TRANSFERRED_IN_LAST_CALL, BYTES_TRANSFERRED_IN_LAST_CALL, size
848 QBGT NO_BD_OFFSET_INCR, BYTES_TRANSFERRED_IN_LAST_CALL, 32
849 SUB BYTES_TRANSFERRED_IN_LAST_CALL, BYTES_TRANSFERRED_IN_LAST_CALL, 32
851 ;check if bytes transferred in last call was more than 32 bytes or not and
852 ;based on it increment the byte count/set it to base or move to next descriptor
853 QBNE NO_QUEUE_WRAP_XMT_1, BUFFER_DESC_OFFSET, TOP_MOST_BUFFER_DESC_OFFSET
854 AND BUFFER_DESC_OFFSET , BASE_BUFFER_DESC_OFFSET , BASE_BUFFER_DESC_OFFSET
855 .if $defined("TWO_PORT_CFG")
856 QBBS QUEUE_WRAP_XMT_1, R13, 2 ;PACKET_FROM_COLL_QUEUE
857 .endif ;TWO_PORT_CFG
858 AND BUFFER_INDEX , BUFFER_OFFSET , BUFFER_OFFSET
859 JMP QUEUE_WRAP_XMT_1
860 NO_QUEUE_WRAP_XMT_1:
861 ADD BUFFER_DESC_OFFSET, BUFFER_DESC_OFFSET, 4 ; working rd_ptr for Tx Queue
862 QUEUE_WRAP_XMT_1:
864 NO_BD_OFFSET_INCR:
865 ;Check whether we have transmitted all the bytes ..if not than call Tx Task again for this packet
866 QBBS no_xmt_over_check, R22, Entire_Tx_Data_Not_Pushed
867 QBEQ XMT_OVER, BYTE_CNT, Packet_Length
868 no_xmt_over_check:
869 CLR R22 , R22 , Entire_Tx_Data_Not_Pushed
870 LDI SHIFT_REG, SHIFT_NONE
871 .if $defined("PRU0")
872 XOUT BANK1, &MII_TX_CONTEXT, 20
873 .else
874 XOUT BANK2, &MII_TX_CONTEXT, 20
875 .endif
876 JMP TASK_EXECUTION_FINISHED
878 XMT_OVER:
879 ;check if link speed is 100 mbps or free space is more than 4 bytes than jump else continue
880 QBBS XMT_LB_1OOMbps_MODE, R23, TX_PHY_SPEED
881 QBLE XMT_LB_1OOMbps_MODE, FREE_SPACE_IN_FIFO, 4
882 JMP TASK_EXECUTION_FINISHED
883 XMT_LB_1OOMbps_MODE:
884 ; Insert the CRC in the outgoing frame by writing to R30
885 .if $defined("ICSS_REV1")
886 M_XMT_INSERT_CRC_ICSS_REV1
887 .endif ;ICSS_REV1
888 .if $defined("ICSS_REV2")
889 M_XMT_INSERT_CRC_ICSS_REV2
890 .endif ;ICSS_REV2
892 ; Don't allow insertion of next packet in TX Fifo unless it is empty
893 CLR R22 , R22 , PACKET_TX_ALLOWED
894 CLR R22 , R22 , Entire_Tx_Data_Not_Pushed
896 xmt_save_context:
898 ; save the context back to the bank
899 LDI SHIFT_REG, SHIFT_NONE
900 .if $defined("PRU0")
901 XOUT BANK1, &MII_TX_CONTEXT, 20
902 .else
903 XOUT BANK2, &MII_TX_CONTEXT, 20
904 .endif
906 ; Set the Tx Stat Pend bit
907 SET R23 , R23 , TX_STAT_PEND
908 ;finally write the final descriptor value that it has been sent
909 QBEQ QUEUE_WRAP_XMT_LB, BYTES_TRANSFERRED_IN_LAST_CALL, 0
910 QBNE NO_QUEUE_WRAP_XMT_LB, BUFFER_DESC_OFFSET, TOP_MOST_BUFFER_DESC_OFFSET
911 AND BUFFER_DESC_OFFSET , BASE_BUFFER_DESC_OFFSET , BASE_BUFFER_DESC_OFFSET
912 JMP QUEUE_WRAP_XMT_LB
913 NO_QUEUE_WRAP_XMT_LB:
914 ADD BUFFER_DESC_OFFSET, BUFFER_DESC_OFFSET, 4 ; working rd_ptr for Tx Queue
916 QUEUE_WRAP_XMT_LB:
918 .if $defined("TWO_PORT_CFG")
919 SBCO &BUFFER_DESC_OFFSET, QUEUE_DESP_BASE, QUEUE_DESC_OFFSET, 2 ; update rd_ptr in the Queue desp.
920 QBBC XMT_NOT_FROM_COLLISION_QUEUE, R13, 2 ;PACKET_FROM_COLL_QUEUE
921 ; Check and Update the wr_ptr of the collision Queue if there was a collision
922 LDI R20.b2, 0
923 LDI R20.w0, COLLISION_STATUS_ADDR
924 .if $defined("PRU0")
925 LDI QUEUE_DESC_OFFSET, P2_COL_QUEUE_DESC_OFFSET
926 LBCO &QUEUE_DESC_REG, QUEUE_DESP_BASE, QUEUE_DESC_OFFSET, 4
927 ADD QUEUE_DESC_OFFSET, QUEUE_DESC_OFFSET, 2
928 SBCO &QUEUE_DESC_REG.rd_ptr, QUEUE_DESP_BASE, QUEUE_DESC_OFFSET, 2
929 ; Clear bit which indicates that data has been transferred from the collision buffer
930 ADD R20.w0, R20.w0, 2
931 SBCO &R20.b2, PRU1_DMEM_CONST, R20.w0, 1
932 .else
933 LDI QUEUE_DESC_OFFSET, P1_COL_QUEUE_DESC_OFFSET
934 LBCO &QUEUE_DESC_REG, QUEUE_DESP_BASE, QUEUE_DESC_OFFSET, 4
935 ADD QUEUE_DESC_OFFSET, QUEUE_DESC_OFFSET, 2
936 SBCO &QUEUE_DESC_REG.rd_ptr, QUEUE_DESP_BASE, QUEUE_DESC_OFFSET, 2
937 ; Clear bit which indicates that data has been transferred from the collision buffer
938 ADD R20.w0, R20.w0, 1
939 SBCO &R20.b2, PRU1_DMEM_CONST, R20.w0, 1
940 .endif
941 .else
942 SBCO &BUFFER_DESC_OFFSET, PRU_DMEM_ADDR, QUEUE_DESC_OFFSET, 2 ; update rd_ptr in the Queue desp.
944 .endif ;TWO_PORT_CFG
945 XMT_NOT_FROM_COLLISION_QUEUE:
948 SKIP_DESC_UPDATE:
949 CLR R23 , R23 , Xmt_active ; clear global flag to indicate the completion of transmission
950 .if $defined(PTP)
951 M_GPTP_SET_CALLBACK_INTERRUPT
952 .endif ;PTP
953 .if $defined("HALF_DUPLEX_ENABLED")
954 QBBC DO_NOT_UPDATE_COLLISION_STATS, R22 , PORT_IS_HALF_DUPLEX
956 ;load collision counter
957 LDI TEMP_REG_1 , COLLISION_COUNTER
958 LBCO &TEMP_REG_2, PRU_DMEM_ADDR, TEMP_REG_1, 1
960 ;Update collision status
961 QBLT UPDATE_MULTIPLE_COLLISION, TEMP_REG_2, 1
962 QBEQ DO_NOT_UPDATE_COLLISION_STATS, TEMP_REG_2, 0
963 LDI TEMP_REG_1 , SINGLE_COLLISION_OFFSET
964 QBA ADD_TX_STATS
965 UPDATE_MULTIPLE_COLLISION:
966 QBLT UPDATE_EXCESS_COLLISION, TEMP_REG_2, 15
967 LDI TEMP_REG_1 , MULTIPLE_COLLISION_OFFSET
968 QBA ADD_TX_STATS
970 UPDATE_EXCESS_COLLISION:
971 LDI TEMP_REG_1 , EXCESS_COLLISION_OFFSET;Reset counter for collision
972 QBA ADD_TX_STATS
974 DO_NOT_UPDATE_COLLISION_STATS:
975 .endif ;HALF_DUPLEX_ENABLED
976 JMP TASK_EXECUTION_FINISHED
978 process_rx_eof_tx_lb:
979 JAL CALL_REG, FN_RCV_LB
981 .endif ; __mii_xmt_p