9d05fbf8892c7618d3cb96fb2af47ab2f8309446
[processor-sdk/pdk.git] / packages / ti / drv / emac / firmware / icss_dualmac / src / rxl2_txl2.asm
1 ;
2 ;  TEXAS INSTRUMENTS TEXT FILE LICENSE
3 ;
4 ;   Copyright (c) 2018-2019 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.
55 ;Basic Ethernet rx/tx firmware==> TASK MANAGER + S&F MODE {{{1
56 ;/ modified by DAL
57 ;TXL2 version
58 ; 'new' rxl2  mode, so eof handling is different
59 ; defines for config
60 ; RGMII: set up for RGMII mode
61 ;  MII : set up for MII mode (RX ok, TX not tested)
62 ; SLICE0 or SLICE1 must be defined  (but not both)
63 ; WAIT_FOR_DEBUGGER:  wait for debugger to attach
64 ; VLAN_ENABLED
65 DATA_ONLY       .set    1 ;control path moved to RTU
67 ; sanity check ;{{{1
68  .if $isdefed("SLICE0") & $isdefed("SLICE1")
69         cant    have SLICE0 and SLICE1
70  .endif
71  .if !$isdefed("SLICE0") & !$isdefed("SLICE1")
72         must    have slice0 or slice1 defined
73  .endif
75 ; includes {{{1
76  .include "regs.h"
77  .include "portq.h"
78  .include "reg_alias.h"
79  .include "smem.h"
80  .include "bsram_pru.h"
81  .include "spin.h"
82  .include "xfr2vbus_widget.h"
83  .include "xfr2psi_widget.h"
84  .include "basicio.h"
85  .include "tm.h"
86  .include "rx.h"
87  .include "tx.h"
88  .include "filter.h"
89  .include "lebe.h"
90  .include "ipc.h"
91  .include "iep.h"
92  .include "psisandf.h"
93  .include "hd_helper.h"
94  .include "pa_stat.h"
96 loop_here       .macro
97 here?:  jmp     here?
98  .endm
100 ; slice0 vs slice1 {{{1
101  .if $isdefed("SLICE0")
102         .asg    MII_RXCFG0_ADDR, MII_RXCFGn_ADDR
103         .asg    0x8, GPCFGn_REG
104         .asg    FDB_XID_PORT0_RES, FDB_XID_PORTn_RES
105         .asg    MII_PRE_CNT0, MII_PRE_CNTn
106  .else
107         .asg    MII_RXCFG1_ADDR, MII_RXCFGn_ADDR
108         .asg    0xc, GPCFGn_REG
109         .asg    FDB_XID_PORT1_RES, FDB_XID_PORTn_RES
110         .asg    MII_PRE_CNT1, MII_PRE_CNTn
111  .endif
112 ;slice0 controls tx1 if switch, tx0 otherwise
113 ;slice1 controls tx0 if switch, tx1 otherwise
114  .if $isdefed("SLICE0")
115         .asg    MII_TXCFG0_ADDR, MII_TXCFGn_ADDR
116         .asg    MII_TXIPG0_ADDR, MII_TXIPGn_ADDR
117  .else
118         .asg    MII_TXCFG1_ADDR, MII_TXCFGn_ADDR
119         .asg    MII_TXIPG1_ADDR, MII_TXIPGn_ADDR
120  .endif
122 ; Enable RX L2 pru0 & rx
123 enable_rx_l2    .macro
124         ldi32   r28, MII_RXCFGn_ADDR
125         lbbo    &r11, r28, 0, 4
126         set     r11.t4 ;rx l2 enable
127         set     r11.t0 ;rx enable
128         set     r11.t9 ;rx_eof_sclr_dis0
129         set     r11.t1 ;make tx eof visible in r31, bit16
130         sbbo    &r11, r28, 0, 4
131  .endm
133 long_preamble_firewall_disable  .macro
134         ldi32   r28, MII_PRE_CNTn
135         lbbo    &r11, r28, 0, 4
136         and     r11.b0, r11.b0, 0x0f
137         sbbo    &r11, r28, 0, 4
138  .endm
140 gpcfg_reg_config        .macro
141         ldi32   r28, PRUSS1_CFG_PRU_OFFSET
142         lbbo    &r11, r28, GPCFGn_REG, 4
143         set     r11.t1
144         set     r11.t0
145         set     r11.t27
146         sbbo    &r11, r28, GPCFGn_REG, 4
147  .endm
149 mii_tx_config   .macro
150         ldi32   r28, MII_TXCFGn_ADDR
151         lbbo    &r11, r28, 0, 4
152         set     r11.t0  ;enable txl1
153         set     r11.t11 ;tx_32_mode en
154         set     r11.t1  ;tx_auto_preamble
155 ;set mux
156  .if $isdefed("SLICE0")
157         clr     r11.t8
158  .else
159         set     r11.t8
160  .endif
161         ldi     r11.b2, 0 ;set tx start delay to 0!!!
162         clr     r11.t25
163         clr     r11.t24
164         sbbo    &r11, r28, 0, 4
165  .endm
167 set_tx_ipg      .macro
168 ;change ipg to 88 ns  (22  250mhz clocks)
169         ldi32   r28, MII_TXIPGn_ADDR
170         lbbo    &r11, r28, 0, 4
171         ldi     r11, 0x16 ; min IPG for testing (CCLINK)
172         sbbo    &r11, r28, 0, 4
173  .endm
175 icss_g_config   .macro
176 ; **for now let slice0 do txl2 & port mode config (ICSS_G register) for both sides {{{2
177 ;TX Config TXl2 - icss_g register
178         ldi32   r28, ICSS_G
179         lbbo    &r11, r28, 0, 4
180         set     r11.t1
181         set     r11.t0
182         set     r11.t2 ;rx_l2_g_en
184  .if $isdefed("RGMII")
185         set     r11.t3
186         clr     r11.t4
187         set     r11.t5
188         clr     r11.t6
189  .endif
190  .if $isdefed("MII")
191         clr     r11.t3
192         clr     r11.t4
193         clr     r11.t5
194         clr     r11.t6
195  .endif
196         sbbo    &r11, r28, 0, 4
197  .endm
199 wait4debugger   .macro
200  .if $isdefed("WAIT_FOR_DEBUGGER")
201         ldi32   r11, 0
202 $1:     qbeq    $1, r11, 0
203  .endif
204  .endm
206 ; we need to read DMA back only if there is ongoing transfer
207 ; assume when we read DMA status it shouldn't be 0,
208 ; otherwise let's think it is already stopped   
209 flush_dma .macro unit
210         XFR2VBUS_CANCEL_READ_AUTO_64_CMD unit
211         nop
212 $1:     xin     unit, &r18, 4
213         qbeq    $2, r18.w0, 0
214         qbne    $1, r18.w0, 0x5
215         XFR2VBUS_READ64_RESULT unit
216 $2:
217         .endm
219 stop_tx_due_colission .macro
220         qbbc    $1, GRegs.tx.b.flags, f_next_dma
221         flush_dma       XFR2VBUS_XID_READ0
222         qba     $2 ;
223 $1:     flush_dma       XFR2VBUS_XID_READ1
224 $2:     set     r31, r31, 29            ;tx.eof
225         set     GRegs.speed_f, GRegs.speed_f, f_stopped_due_col
226         ldi     GRegs.tx.b.state, TX_S_W_EOF
227         .endm
229 ; Code starts {{{1
230  .retain     ; Required forbuilding     .out with assembly file
231  .retainrefs ; Required forbuilding     .out with assembly file
232  .sect    ".text:Start"
233  .global  Start
235 Start:
236         TM_DISABLE
237         ldi32   r0, 0x80000000  ;TODO: driver has to enable PA_STAT
238         ldi32   r1, 0x3c000
239         sbbo    &r0, r1, 8, 4
241         zero    &r0, 124
242         P2P_IPC_ZAP     ;zap IPC area
243         xout    XFR2VBUS_XID_READ0, &r18, 4 ;disable xfr2vbus autoread mode
244         xout    XFR2VBUS_XID_READ1, &r18, 4 ;
246 ;Initialization:  set up RX & TX MII stuff.
247         enable_rx_l2
248         long_preamble_firewall_disable
249         gpcfg_reg_config        ; 0x0800_0003
250         mii_tx_config
251         set_tx_ipg
252         icss_g_config
254         wait4debugger
256         set     r31, r31, 18 ;RX reset
257 ;setup BSRAM
258         BSRAM_ZERO_BANK r1
260 ;SETUP portQ for to-host traffic, in order to do sandf PSI
261         PSIQ_CREATE
263 ;set up PSI INFO, CONTROL, STATUS TEMPLATES
264  .if $isdefed("SLICE0")
265         PSI_SETUP_INFO  PSI_INFO_SLOT, 1
266  .else
267         PSI_SETUP_INFO  PSI_INFO_SLOT, 2
268  .endif
269         PSI_SETUP_STATUS        PSI_STATUS_SLOT
271 ;VA we should start here
272         ldi     GRegs.pkt_cnt.x, 0
274 ;START RX/TX of 1 packet burst ; {{{1
275 RX:
276         RX_TASK_INIT
277 ;setup taskmanager
278         TM_PRU_CONFIG   RX_SOF, RX_B0, RX_B1, RX_BN, RX_EOF, TX_NOP, TX_NOP, TX_FIFO, TX_EOF, RXTX_ERR
279         TM_ENABLE
280         set     r31.t18 ;RX reset
281         ldi     r18, 0
282         xout    40, &r18, 4 ;set tx fifo mode
284 ;read in global state
285         ldi     GRegs.pkt_cnt.x, 0
286         ldi     GRegs.tx.b.state, 0
287         ldi     GRegs.rx.x, 0
288         ldi     GRegs.snf.b.wr_cur, MINPS
289         ldi     GRegs.snf.b.rd_cur, MINPS
290         ldi     r30, 1522  ;todo - make a parameter
291         ldi32   r10, FW_CONFIG
293 ; set pru ready status
294         ldi32   r0, PRU_READY
295         sbbo    &r0, r10, CFG_STATUS, 4
296 ; wait rtu ready
297         ldi32   r1, RTU_READY
298 wait_rtu_ready:
299         lbbo    &r0, r10, CFG_RTU_STATUS, 4
300         qbne    wait_rtu_ready, r0, r1
301 ; let's go
303 ;-------------------------------------------------------------------
304 ;BG TASK:     r24-r29  are global ;{{{1
305 ;-------------------------------------------------------------------------
306         zero    &r18, 24
308         ldi     GRegs.ret_cnt, 0
309 ;================================
310 ; BG LOOP:  until cmd cancel seen
311 ;================================
312 bg_loop:
313         add     BgRegs.bg_cnt, BgRegs.bg_cnt, 1 ;loop count
314 ; if RTU started shutdown process - disable TM and loop forever
315         ldi32   r0, FW_CONFIG
316         ldi32   r1, RTU_STARTED_SHUTDOWN
317         lbbo    &r9, r0, CFG_RTU_STATUS, 4
318         qbne    skip_chk01, r9, r1
319 ;disable xfr2vbus autoread mode
320         ldi32   r18, 0
321         xout    XFR2VBUS_XID_READ0, &r18, 4
322         xout    XFR2VBUS_XID_READ1, &r18, 4
324         PSI_ABORT
325 ;       if we are here, we can place debug error code somewere in the SMEM
326         TM_DISABLE
327         ldi32   r1, PRU_STOPPED
328         sbbo    &r1, r0, CFG_STATUS, 4
329         loop_here
331 skip_chk01:
332 ;-----------------------
333 ;schedule TX2HOST?
334 ;----------------------
335 ; do nothing if widget is full!!
336         xin     XID_PSI_S, &r1,8
337         qbbc    scheduler, r2,TB_WRITE
338         qbeq    th_schedule0, BgRegs.psi2h_active, 0
339 ; active 2host
340         PSISANDF_TX     bg_to_host2, scheduler
341 bg_to_host2:  ;go again
342         xin     XID_PSI_S, &r1,8
343         qbbc    scheduler, r2,TB_WRITE
344         PSISANDF_TX     scheduler, scheduler
345         jmp     scheduler  ;just in case
346 th_schedule0:
347         qbeq scheduler, GRegs.psiq.b.num_elem, 0
348 ; have new packet to send
349         TM_DISABLE
350         PSIQ_POP
351         TM_ENABLE
352 ;r2 = flow | len  r3 = starting read index
353         PSISANDF_TX_INIT2       r2, r3
355 ;-----------------------
356 ;schedule TX2WIRE ?
357 ;----------------------
358 scheduler:
359         READ_RGMII_CFG  r2, GRegs.speed_f               ; update speed/duplex fields
360         sbco    &r25, c28, 0x20, 4
361         qbbs    sch_10, GRegs.speed_f, f_half_d ; don't check col if full duplex
362 ; if TX is idle and colission is set, probably it is from the
363 ; previouse packet. Just wait
364         read_col_status r2
365         qbne    sch_05, GRegs.tx.b.state, TX_S_IDLE ; TODO: check error case
366         qbbs    bg_loop, r2, 1  ; still active
367 sch_05: qbbc    sch_10,  r2, 1  ;
368 ; we came here if TX is active and collission is detected
369 ; we need to cancel the current TX and schedule retransmission
370         qbbs    sch_10, GRegs.speed_f, f_stopped_due_col ; don't stop twice
371         TM_DISABLE
372         set     GRegs.speed_f, GRegs.speed_f, f_col_detected
373         flip_tx_r0_r23
374         stop_tx_due_colission
375         flip_tx_r0_r23
376         TM_ENABLE
377 sch_10:
378         TM_DISABLE
379         ;if tx state is idle, check IPC for new descriptor
380         qbeq    bg_schedule0, GRegs.tx.b.state, TX_S_IDLE
381         qbne    sched_done, GRegs.tx.b.state, TX_S_ERR
382 ;error case (underflow)
383 ;todo
384         ldi     GRegs.tx.b.state, TX_S_IDLE
385 sched_done:
386         TM_ENABLE
387         jmp     bg_loop
389 bg_schedule0:
390         ldi     GRegs.tx_blk, 0
391         clr     GRegs.speed_f, GRegs.speed_f, f_col_detected
392         clr     GRegs.speed_f, GRegs.speed_f, f_stopped_due_col
393         qbbs    bg_new_pkt, GRegs.speed_f, f_1gbps      ; process as usual
394         qbbc    bg_half_duplex, GRegs.speed_f, f_half_d ;
395 bg_schedule1:
396         qbbs    bg_new_pkt, GRegs.speed_f, f_100mbps    ;
397         if_ipg_not_expired      sched_done
398         qba     bg_new_pkt
400 bg_half_duplex:
401         qbne    sched_done, GRegs.rx.b.state, RX_STATE_IDLE ; we have active RX,don't start TX
402         qbeq    bg_schedule1, GRegs.ret_cnt, 0  ; just new packet
403         if_ipg_not_expired sched_done
404 ; OK we need to restart transmition of the same packet
405 ; use the same dma, which was used for the packet
406         qbbc    retr_1, GRegs.tx.b.flags, f_next_dma
407         read_bd_from_smem  r2, BD_OFS_0
408         XFR2VBUS_ISSUE_READ_AUTO_64_CMD XFR2VBUS_XID_READ0, r2, ADDR_HI
409         TM_ENABLE
410         XFR2VBUS_WAIT4READY     XFR2VBUS_XID_READ0
411         qba     retr_2
412 retr_1:
413         read_bd_from_smem  r2, BD_OFS_1
414         XFR2VBUS_ISSUE_READ_AUTO_64_CMD XFR2VBUS_XID_READ1, r2, ADDR_HI
415         TM_ENABLE
416         XFR2VBUS_WAIT4READY     XFR2VBUS_XID_READ1
418 retr_2: TM_DISABLE
419         TX_TASK_INIT2_shell     r3
420         TM_ENABLE
421         jmp     bg_loop
423 bg_new_pkt:
424         ldi     GRegs.ret_cnt, 0
425         qbbs    bg_chk1, GRegs.tx.b.flags, f_next_dma
426         PRU_IPC_RX_CH0Q sched_done, r2, XFR2VBUS_XID_READ0
427         TX_TASK_INIT2_shell     r2
428         set     GRegs.tx.b.flags, GRegs.tx.b.flags, f_next_dma
429         TM_ENABLE
430         jmp     bg_loop
431 bg_chk1:
432         PRU_IPC_RX_CH0Q sched_done, r3, XFR2VBUS_XID_READ1
433         TX_TASK_INIT2_shell     r3
434         clr     GRegs.tx.b.flags, GRegs.tx.b.flags, f_next_dma
435         TM_ENABLE
436         jmp     bg_loop
438 ;-------------------------------------
439 ; done with packets.
440 ;-------------------------------------
441 bg_done:
443 ;save bg info:  bg loops, txstate, rxstate, (pkt counts)
444         PAGE_RESTORE    BG_STATE, 32
445         mov     r2, BgRegs.bg_cnt
446         mov     r3, GRegs.tx.x 
447         mov     r4, GRegs.rx.x
448         mov     r5, GRegs.pkt_cnt.x
449         PAGE_SAVEQ
451 ;update result area (length)
452         ldi32   r1, FW_CONFIG
453         sbbo    &r2, r1, CFG_OUT, 20
454         ldi32   r2, 0x10000001
455         sbbo    &r2, r1, CFG_STATUS, 4
456         loop_here
458 ;-------------------------------------------------------------------------
459 ;end BG task
460 ;-------------------------------------------------------------------------
462 ;---------------------------------------------------------------------
463 ; TX_EOF  EvENT {{{1
464 ;---------------------------------------------------------------------
465 TX_EOF:
466         qbne    tx_underflow, GRegs.tx.b.state, TX_S_W_EOF
467         flip_tx_r0_r23
468         m_inc_stat      r0.b0, 82
469         qbbs    tx_proc_col, GRegs.speed_f, f_stopped_due_col
470 ; TX TS processing
471         qbbc    no_tx_ts, TxRegs.ds_flags, 5 ; we don't need tx_ts
472         GET_PKT_TX_TS   r2
473         ldi32   r10, FW_CONFIG + TX_TS_BASE
474         sbbo    &r2, r10, 0, 8
475         SPIN_TOG_LOCK_LOC       PRU_RTU_TX_TS_READY
476 no_tx_ts:
477 ;       if half duplex IPC to RTU
478         qbbs    tx_eof_0, GRegs.speed_f, f_half_d
479         qbbs    tx_eof_ipc1, GRegs.tx.b.flags, f_next_dma       
480         SPIN_TOG_LOCK_LOC PRU_RTU_EOD_P_FLAG
481         qba     tx_eof_0
482 tx_eof_ipc1:
483         SPIN_TOG_LOCK_LOC PRU_RTU_EOD_E_FLAG
484 ; we don't check if the next packet scheduled for 10Mbps 
485 tx_eof_0:
486         qbbs    tx_eof_1, GRegs.speed_f, f_1gbps
487         qbbc    no_new_tx_10mbps, GRegs.speed_f, f_100mbps
488 tx_eof_1:       
489         ldi     GRegs.tx_blk, 0
490         clr     GRegs.speed_f, GRegs.speed_f, f_col_detected
491         clr     GRegs.speed_f, GRegs.speed_f, f_stopped_due_col
492         ldi     GRegs.ret_cnt, 0
494         qbbs    teof_chk1, GRegs.tx.b.flags, f_next_dma
495         PRU_IPC_RX_CH0Q no_new_tx, r2, XFR2VBUS_XID_READ0
496         TX_TASK_INIT2   r2
497         set     GRegs.tx.b.flags, GRegs.tx.b.flags, f_next_dma 
498         jmp     tx_eof_on_deck_done
499 teof_chk1:
500         PRU_IPC_RX_CH0Q no_new_tx, r3, XFR2VBUS_XID_READ1
501         TX_TASK_INIT2   r3
502         clr     GRegs.tx.b.flags, GRegs.tx.b.flags, f_next_dma
504 tx_eof_on_deck_done:
505         TM_YIELD
506         flip_tx_r0_r23
507         add     GRegs.pkt_cnt.w.tx, GRegs.pkt_cnt.w.tx, 1
508         loop_here
510 no_new_tx_10mbps:
511         ldi     GRegs.tx_blk, 0
512         clr     GRegs.speed_f, GRegs.speed_f, f_col_detected
513         clr     GRegs.speed_f, GRegs.speed_f, f_stopped_due_col
514         ldi     GRegs.ret_cnt, 0
515         start_ipg_timer 
517 no_new_tx:
518         ldi     GRegs.tx.b.state, TX_S_IDLE
519         qba     tx_eof_on_deck_done
521 ; we came here due to collision, so we are in half duplex mode.
522 ; We either retranssmit or drop the packet
523 ;  
524 tx_proc_col:
525         m_inc_stat      r1.b0, TX_COL_RETRIES
526         qble    txp_max_retry, GRegs.ret_cnt, 16 ; todo: define
527         qblt    txp_max_retry, GRegs.tx_blk, 2   ; TODO: update for late col
528         start_backoff_timer GRegs.ret_cnt
529         add     GRegs.ret_cnt, GRegs.ret_cnt, 1
530         qba     no_new_tx 
531 txp_max_retry:
532         m_inc_stat      r1.b0, TX_COL_DROPPED
533         qbbs    txp_max_01, GRegs.tx.b.flags, f_next_dma        
534         SPIN_TOG_LOCK_LOC PRU_RTU_EOD_P_FLAG
535         qba     txp_max_02
536 txp_max_01:
537         SPIN_TOG_LOCK_LOC PRU_RTU_EOD_E_FLAG
538 txp_max_02:
539         start_ipg_timer
540         ldi     GRegs.ret_cnt, 0
541         qbbc    no_new_tx_10mbps, GRegs.speed_f, f_100mbps
542         qba     no_new_tx
543         
544 ;------exception cases------
545 tx_underflow:
546         ldi     GRegs.tx.b.state, TX_S_ERR
547         TM_YIELD
548         add     GRegs.pkt_cnt.w.tx, GRegs.pkt_cnt.w.tx, 1
549         loop_here
551 ;---------------------------------------------------------------------
552 ;  ENd TX_EOF
553 ;----------------------------------------------------------------------
555 ;---------------------------------------------------------------------
556 ; TX_FIFO  EVENT {{{1
557 ;----------------------------------------------------------------------
558 TX_FIFO:
559         qbeq    handle_portq, GRegs.tx.b.state, TX_S_ACTIVE
560         TM_YIELD
561         loop_here
563 handle_portq:
564         flip_tx_r0_r23
565         add     GRegs.tx_blk, GRegs.tx_blk, 1
566         qbbs    tx_fifo1, GRegs.speed_f, f_half_d
567         qbbs    txf_90, GRegs.speed_f, f_stopped_due_col ; don't stop twice
568         
569         update_col_status
570         qbbc    tx_fifo1, GRegs.speed_f, f_col_detected
571         ; collision was detected, we need to stop pushing to TXL2
572         stop_tx_due_colission
573         qba     txf_90
575 tx_fifo1:
576         TX_FILL_FIFO    XFR2VBUS_XID_READ0
577 txf_90: TM_YIELD
578         flip_tx_r0_r23
579         loop_here
581 ;-------------------------------------------------------------------------
582 ;RXTX_ERR EVENT  ; {{{1
583 ; assume rx issue.
584 ; reset rxl2 fifo
585 ; hopefully that cleans things up
586 ;  need to see what else needs to be done
587 RXTX_ERR:
588         flip_tx_r0_r23
589         qbne    rx_err?, GRegs.tx.b.state, TX_S_ERR
590         ; wait DMA ir complete
591         qbbs    $3, TxRegs.ds_flags, 4
592 $1:     xin     XFR2VBUS_XID_READ0, &r18, 4
593         qbeq    $2, r18.w0, 0x5
594         qbeq    $2, r18, 0
595         qba     $1
596 $2:     nop
597         XFR2VBUS_CANCEL_READ_AUTO_64_CMD XFR2VBUS_XID_READ0
598         nop
599         XFR2VBUS_READ64_RESULT XFR2VBUS_XID_READ0
600         SPIN_SET_LOCK_LOC PRU_RTU_EOD_P_FLAG
601         SPIN_CLR_LOCK_LOC PRU_RTU_EOD_P_FLAG
602         jmp     $5
603 $3:     xin     XFR2VBUS_XID_READ1, &r18, 4
604         qbeq    $4, r18.w0, 0x5
605         qbeq    $4, r18, 0
606         qba     $3
607 $4:     nop
608         XFR2VBUS_CANCEL_READ_AUTO_64_CMD XFR2VBUS_XID_READ1
609         nop
610         XFR2VBUS_READ64_RESULT XFR2VBUS_XID_READ1
611         SPIN_SET_LOCK_LOC PRU_RTU_EOD_E_FLAG
612         SPIN_CLR_LOCK_LOC PRU_RTU_EOD_E_FLAG
613 $5:
614         set     r31.t30; TX_RESET
615         nop
616         nop
617         ;set TX to TX_S_IDLE
618         ldi     GRegs.tx.b.state, TX_S_IDLE
619         qba     rxtx_err_exit
620 rx_err?
621         ldi     r11.b3, 0x80
622         xout    22, &r11, 4
623         set     r31.t22  ; clear rx eof  (why isnt it bit 20?)
624         ldi     r7, 1  ;indicate we drop
625 ;for now assume it is the RXL1 overflowing for next frame
626 ;todo: how to check to see if it is for this frame??
627         ldi     GRegs.rx.b.state, RX_STATE_OVER0
628 rxtx_err_exit:
629         TM_YIELD
630         flip_tx_r0_r23
631         loop_here
633 ;-------------------------------------------------------------------------
634 ; Dummy: TX_NOP {{{1
635 ;-------------------------------------------------------------------------
636 TX_NOP:
637         TM_YIELD
638         loop_here
639 ;----------------------------------------------------------------------
640 ; Dummy: END TX_NOP
641 ;-------------------------------------------------------------------------
643 ;---------------------------------------------------------------
644 ; RX TASK, State 1:  RX  SOF {{{1
645 ;--------------------------------------------------------------
646 RX_SOF:
647 ;turn off RX_SOF
648         TM_YIELD
649         loop_here
650 ;---------------------------------------------------------------
651 ; END RX TASK, State 1
652 ;--------------------------------------------------------------
654 NBTR    .set    32
655 ;---------------------------------------------------------------
656 ; RX TASK, State 2: RX_B0 {{{1
657 ;--------------------------------------------------------------
658 RX_B0:
659         flip_rx_r0_r23
661 ;BRING IN THE DATA
662         xin     RXL2_BANK0, &r2, NBTR
663         ldi     RxRegs.aux_flags, 1
664         qbeq    rxb0_already_over, GRegs.rx.b.state, RX_STATE_OVER0
666         ldi     GRegs.rx.x, 0x180 ;fresh state=1, (sof flag set)
667         P_W32_S rxb0_full  ;stash pkt bytes in bs slot but don't start
669         jmp     rx_b0_done
671 ;some error/exception cases handling here
672 rxb0_full:  ;psi fifo in bsram full
673         P_W32_ABORT
674         ldi     GRegs.rx.x, 0x7F80
675         add     GRegs.snf.b.dbg_cnt, GRegs.snf.b.dbg_cnt, 1
676         jmp     rx_b0_done
678 rxb0_already_over:
679         ldi     GRegs.rx.x, 0x7F80
680 ;todo: bump stats
682 rx_b0_done:
683         TM_YIELD
684         flip_rx_r0_r23
685         add     GRegs.rx.b.pkt_len, GRegs.rx.b.pkt_len, 32 ;hopefully this gets executed!!
686         loop_here
687 ;---------------------------------------------------------------
688 ; END RX TASK, State 2
689 ;--------------------------------------------------------------
691 ;---------------------------------------------------------------
692 ; RX TASK, State 3: RX_B1 {{{1
693 ;--------------------------------------------------------------
694 RX_B1:
695         flip_rx_r0_r23
696         qbeq    skip_b1, GRegs.rx.b.state, RX_STATE_DROP
697 ;!!better be here!!
698 ;r5.b0 = route info
699 ;r5.b1 = fid
700 ;r5.w2 = index
701 ;r6 = buffer ptr for s&f
702         ldi     r0.b1, 0
703 stall_loop:
704         PRU_IPC_RX_CH1
705         qbbs    got_ipc, r5.b0, f_rx_sof
706         add     r0.b1, r0.b1, 1
707         qbne    stall_loop, r0.b1, RB1_STALL_LIMIT
708         ldi     GRegs.rx.b.state, RX_STATE_DROP ;stall limit reached
709         jmp     rb1_ipc_done
710 got_ipc:
711         mov     GRegs.rx.b.flags, r5.b0 ;forwarding info we got from RTU
712         PRU_IPC_RX_CH1_CLRB7    ;clear bit so we know we got it
713         mov     RxRegs.pq_cur, r6 ;save buffer pointer (may not use)  ;=flow in MAC
715 rb1_ipc_done:
716         xin     RXL2_BANK1, &r2, 32 ;bring in data (r2-r9)
717         clr     RxRegs.aux_flags, RxRegs.aux_flags, f_fh
718         set     RxRegs.aux_flags, RxRegs.aux_flags, f_b1_seen
720         TM_DISABLE
721         qbbc    b1_rx_path1a, GRegs.rx.b.flags, f_tohost
722         P_W32   rxb1_full  ;stash pkt bytes in bs slot
723         jmp     rx_b1_done
724 rxb1_full:
725         ldi     GRegs.rx.x, 0x7F80
726         add     GRegs.snf.b.dbg_cnt, GRegs.snf.b.dbg_cnt,1
727 b1_rx_path1a:
728         P_W32_ABORT ;abort the stashing of pkt in BS (for PSI)
729 rx_b1_done:
730         TM_ENABLE
731 b1_exit:TM_YIELD
732         flip_rx_r0_r23
733         add     GRegs.rx.b.pkt_len, GRegs.rx.b.pkt_len, 32
734         loop_here
736 skip_b1:xin     RXL2_BANK1, &r2, 32  ;error case. just read in data and drop
737         clr     RxRegs.aux_flags, RxRegs.aux_flags, f_fh
738         jmp     b1_exit
739 ;---------------------------------------------------------------
740 ; END RX TASK, State 3
741 ;--------------------------------------------------------------
743 ;---------------------------------------------------------------
744 ; RX TASK, State 4: RX_BN {{{1
745 ;--------------------------------------------------------------
746 RX_BN:
747         flip_rx_r0_r23
748 ;check for overflow/drop or pkt too long
749         qbne    pkt_ok, GRegs.rx.b.state, RX_STATE_DROP
750 ;errors:
751         ldi     GRegs.rx.x, 0x7f80  ;indicate we need to drop
752         qbbs    rx_bnerr_sideB, RxRegs.aux_flags, f_fh
753 ;side A
754         xin     RXL2_BANK0, &r2, 32
755         jmp     rx_bn_done
756 rx_bnerr_sideB:
757 ;side B
758         xin     RXL2_BANK1, &r2, 32
759         jmp     rx_bn_done
760 rxbn_full:
761         ldi     GRegs.rx.x, 0x7f80  ;indicate we need to drop
762         P_W32_ABORT
763         add     GRegs.snf.b.dbg_cnt, GRegs.snf.b.dbg_cnt,1
764         jmp     rx_bn_done
766 ;take pkt, all good
767 pkt_ok: qbbs    rx_bn_sideB, RxRegs.aux_flags, f_fh
768         xin     RXL2_BANK0, &r2, 32
769         set     RxRegs.aux_flags, RxRegs.aux_flags, f_fh
770         jmp     bn_cont1
771 rx_bn_sideB:
772         xin     RXL2_BANK1, &r2, 32
773         clr     RxRegs.aux_flags, RxRegs.aux_flags, f_fh
774 bn_cont1:
775         qbbc    rx_bn_done, GRegs.rx.x, 0
776         P_W32   rxbn_full
777 rx_bn_done:
778         TM_YIELD
779         flip_rx_r0_r23
780         add     GRegs.rx.b.pkt_len, GRegs.rx.b.pkt_len, 32
781         loop_here
782 ;---------------------------------------------------------------
783 ; END RX TASK, State 4
784 ;--------------------------------------------------------------
786 ;---------------------------------------------------------------
787 ; RX TASK, State 5: RX_EOF {{{1
788 ;--------------------------------------------------------------
789 RX_EOF:
790         TM_DISABLE
791         flip_rx_r0_r23
792         qbeq    no_rx_sof, GRegs.rx.b.state, RX_STATE_DROP
793         qbbc    no_rx_sof, GRegs.rx.b.flags, f_rx_sof
794         ldi     r0.w0, 0x3310
795         and     r0.w0, r31.w2, r0.w0
796         qbne    beof_rx_err, r0.b0, 0x10 ;check for rx errors
797         qbbs    rx_beof_sideB, RxRegs.aux_flags, f_fh
799 ;side A, r18 and r0.b0  has length
800         RX_EOF_RCV_BANK0
801         ldi     r11.b3, 0x80
802         xout    22, &r11, 4
803         set     r31.t22 ; clear rx eof  (why isnt it bit 20?)
804         mov     RxRegs.res1, r0.b0
805         jmp     rx_beof_cont0
807 rx_beof_sideB:
808 ;side B, r18 and r0.b0  has length
809         RX_EOF_RCV_BANK1
810         ldi     r11.b3, 0x80
811         xout    22, &r11, 4
812         set     r31.t22 ; clear rx eof  (why isnt it bit 20?)
813         add     RxRegs.res1, r0.b0, 32
815 rx_beof_cont0:
816         add     GRegs.rx.b.pkt_len, GRegs.rx.b.pkt_len, r0.b0
817         qbbc    rx_eof_done, GRegs.rx.b.flags, f_tohost
818 ;check for pkt to long
819         qbge    th_pkt_ok, GRegs.rx.b.pkt_len, r30.w0
820         add     r30.w2, r30.w2,1   ; max error (like crc)
821         P_W32_ABORT
822         jmp     rx_eof_done
823 th_pkt_ok:
824 ; push 32 to bsram fifo (not all will be valid)
825         P_W32   rxeof_noroom
826 ; push 'descriptor' to local queue. will be popped by bg task
827         mov     r2.w2, RxRegs.pq_cur       ;flow
828         mov     r2.w0, GRegs.rx.b.pkt_len
829         mov     r3, GRegs.snf.x      ;bsram fifo position (maybe not necessary)
830 ;to do add rxtx timestamp
831         PSIQ_PUSH       rxeof_qfull
833 rx_eof_done:
834         ; check for runt packet
835         qble    rx_eof_done_b, GRegs.rx.b.pkt_len, 64
836         set     r31.t18         ;reset RX_fifo
838 rx_eof_done_b:
839         TM_ENABLE
840         flip_rx_r0_r23
841         TM_YIELD
842         ldi     GRegs.rx.s.fl_n_state, 0
843         add     GRegs.pkt_cnt.w.rx, GRegs.pkt_cnt.w.rx, 1 ;also should tell bg #of pkts we have procesed
844         loop_here
846 ;----------------------------
847 ; bad frame, error handling
848 ;-----------------------------
849 rxeof_noroom:
850 rxeof_qfull:
851         P_W32_ABORT
852         add     GRegs.snf.b.dbg_cnt, GRegs.snf.b.dbg_cnt,1
853         jmp     rx_eof_done
855 beof_rx_err:
856 no_rx_sof:
857 ;saw no sof before eof or other such issues
858         ldi     r11.b3, 0x80
859         xout    22, &r11, 4
860         set     r31, r31, 22 ; clear rx eof  (why isnt it bit 20?)
861         jmp rx_eof_done
862 ;---------------------------------------------------------------
863 ; END RX TASK, State 5
864 ;--------------------------------------------------------------
866  .include "resource_table.h"