Merge pull request #31 in PROCESSOR-SDK/pdk from prsdk-7319 to master
[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 ;       if we are here, we can place debug error code somewere in the SMEM
325         TM_DISABLE
326         ldi32   r1, PRU_STOPPED
327         sbbo    &r1, r0, CFG_STATUS, 4
328         loop_here
330 skip_chk01:
331 ;-----------------------
332 ;schedule TX2HOST?
333 ;----------------------
334 ; do nothing if widget is full!!
335         xin     XID_PSI_S, &r1,8
336         qbbc    scheduler, r2,TB_WRITE
337         qbeq    th_schedule0, BgRegs.psi2h_active, 0
338 ; active 2host
339         PSISANDF_TX     bg_to_host2, scheduler
340 bg_to_host2:  ;go again
341         xin     XID_PSI_S, &r1,8
342         qbbc    scheduler, r2,TB_WRITE
343         PSISANDF_TX     scheduler, scheduler
344         jmp     scheduler  ;just in case
345 th_schedule0:
346         qbeq scheduler, GRegs.psiq.b.num_elem, 0
347 ; have new packet to send
348         TM_DISABLE
349         PSIQ_POP
350         TM_ENABLE
351 ;r2 = flow | len  r3 = starting read index
352         PSISANDF_TX_INIT2       r2, r3
354 ;-----------------------
355 ;schedule TX2WIRE ?
356 ;----------------------
357 scheduler:
358         READ_RGMII_CFG  r2, GRegs.speed_f               ; update speed/duplex fields
359         sbco    &r25, c28, 0x20, 4
360         qbbs    sch_10, GRegs.speed_f, f_half_d ; don't check col if full duplex
361 ; if TX is idle and colission is set, probably it is from the
362 ; previouse packet. Just wait
363         read_col_status r2
364         qbne    sch_05, GRegs.tx.b.state, TX_S_IDLE ; TODO: check error case
365         qbbs    bg_loop, r2, 1  ; still active
366 sch_05: qbbc    sch_10,  r2, 1  ;
367 ; we came here if TX is active and collission is detected
368 ; we need to cancel the current TX and schedule retransmission
369         qbbs    sch_10, GRegs.speed_f, f_stopped_due_col ; don't stop twice
370         TM_DISABLE
371         set     GRegs.speed_f, GRegs.speed_f, f_col_detected
372         flip_tx_r0_r23
373         stop_tx_due_colission
374         flip_tx_r0_r23
375         TM_ENABLE
376 sch_10:
377         TM_DISABLE
378         ;if tx state is idle, check IPC for new descriptor
379         qbeq    bg_schedule0, GRegs.tx.b.state, TX_S_IDLE
380         qbne    sched_done, GRegs.tx.b.state, TX_S_ERR
381 ;error case (underflow)
382 ;todo
383         ldi     GRegs.tx.b.state, TX_S_IDLE
384 sched_done:
385         TM_ENABLE
386         jmp     bg_loop
388 bg_schedule0:
389         ldi     GRegs.tx_blk, 0
390         clr     GRegs.speed_f, GRegs.speed_f, f_col_detected
391         clr     GRegs.speed_f, GRegs.speed_f, f_stopped_due_col
392         qbbs    bg_new_pkt, GRegs.speed_f, f_1gbps      ; process as usual
393         qbbc    bg_half_duplex, GRegs.speed_f, f_half_d ;
394 bg_schedule1:
395         qbbs    bg_new_pkt, GRegs.speed_f, f_100mbps    ;
396         if_ipg_not_expired      sched_done
397         qba     bg_new_pkt
399 bg_half_duplex:
400         qbne    sched_done, GRegs.rx.b.state, RX_STATE_IDLE ; we have active RX,don't start TX
401         qbeq    bg_schedule1, GRegs.ret_cnt, 0  ; just new packet
402         if_ipg_not_expired sched_done
403 ; OK we need to restart transmition of the same packet
404 ; use the same dma, which was used for the packet
405         qbbc    retr_1, GRegs.tx.b.flags, f_next_dma
406         read_bd_from_smem  r2, BD_OFS_0
407         XFR2VBUS_ISSUE_READ_AUTO_64_CMD XFR2VBUS_XID_READ0, r2, ADDR_HI
408         TM_ENABLE
409         XFR2VBUS_WAIT4READY     XFR2VBUS_XID_READ0
410         qba     retr_2
411 retr_1:
412         read_bd_from_smem  r2, BD_OFS_1
413         XFR2VBUS_ISSUE_READ_AUTO_64_CMD XFR2VBUS_XID_READ1, r2, ADDR_HI
414         TM_ENABLE
415         XFR2VBUS_WAIT4READY     XFR2VBUS_XID_READ1
417 retr_2: TM_DISABLE
418         TX_TASK_INIT2_shell     r3
419         TM_ENABLE
420         jmp     bg_loop
422 bg_new_pkt:
423         ldi     GRegs.ret_cnt, 0
424         qbbs    bg_chk1, GRegs.tx.b.flags, f_next_dma
425         PRU_IPC_RX_CH0Q sched_done, r2, XFR2VBUS_XID_READ0
426         TX_TASK_INIT2_shell     r2
427         set     GRegs.tx.b.flags, GRegs.tx.b.flags, f_next_dma
428         TM_ENABLE
429         jmp     bg_loop
430 bg_chk1:
431         PRU_IPC_RX_CH0Q sched_done, r3, XFR2VBUS_XID_READ1
432         TX_TASK_INIT2_shell     r3
433         clr     GRegs.tx.b.flags, GRegs.tx.b.flags, f_next_dma
434         TM_ENABLE
435         jmp     bg_loop
437 ;-------------------------------------
438 ; done with packets.
439 ;-------------------------------------
440 bg_done:
442 ;save bg info:  bg loops, txstate, rxstate, (pkt counts)
443         PAGE_RESTORE    BG_STATE, 32
444         mov     r2, BgRegs.bg_cnt
445         mov     r3, GRegs.tx.x 
446         mov     r4, GRegs.rx.x
447         mov     r5, GRegs.pkt_cnt.x
448         PAGE_SAVEQ
450 ;update result area (length)
451         ldi32   r1, FW_CONFIG
452         sbbo    &r2, r1, CFG_OUT, 20
453         ldi32   r2, 0x10000001
454         sbbo    &r2, r1, CFG_STATUS, 4
455         loop_here
457 ;-------------------------------------------------------------------------
458 ;end BG task
459 ;-------------------------------------------------------------------------
461 ;---------------------------------------------------------------------
462 ; TX_EOF  EvENT {{{1
463 ;---------------------------------------------------------------------
464 TX_EOF:
465         qbne    tx_underflow, GRegs.tx.b.state, TX_S_W_EOF
466         flip_tx_r0_r23
467         m_inc_stat      r0.b0, 82
468         qbbs    tx_proc_col, GRegs.speed_f, f_stopped_due_col
469 ; TX TS processing
470         qbbc    no_tx_ts, TxRegs.ds_flags, 5 ; we don't need tx_ts
471         GET_PKT_TX_TS   r2
472         ldi32   r10, FW_CONFIG + TX_TS_BASE
473         sbbo    &r2, r10, 0, 8
474         SPIN_TOG_LOCK_LOC       PRU_RTU_TX_TS_READY
475 no_tx_ts:
476 ;       if half duplex IPC to RTU
477         qbbs    tx_eof_0, GRegs.speed_f, f_half_d
478         qbbs    tx_eof_ipc1, GRegs.tx.b.flags, f_next_dma       
479         SPIN_TOG_LOCK_LOC PRU_RTU_EOD_P_FLAG
480         qba     tx_eof_0
481 tx_eof_ipc1:
482         SPIN_TOG_LOCK_LOC PRU_RTU_EOD_E_FLAG
483 ; we don't check if the next packet scheduled for 10Mbps 
484 tx_eof_0:
485         qbbs    tx_eof_1, GRegs.speed_f, f_1gbps
486         qbbc    no_new_tx_10mbps, GRegs.speed_f, f_100mbps
487 tx_eof_1:       
488         ldi     GRegs.tx_blk, 0
489         clr     GRegs.speed_f, GRegs.speed_f, f_col_detected
490         clr     GRegs.speed_f, GRegs.speed_f, f_stopped_due_col
491         ldi     GRegs.ret_cnt, 0
493         qbbs    teof_chk1, GRegs.tx.b.flags, f_next_dma
494         PRU_IPC_RX_CH0Q no_new_tx, r2, XFR2VBUS_XID_READ0
495         TX_TASK_INIT2   r2
496         set     GRegs.tx.b.flags, GRegs.tx.b.flags, f_next_dma 
497         jmp     tx_eof_on_deck_done
498 teof_chk1:
499         PRU_IPC_RX_CH0Q no_new_tx, r3, XFR2VBUS_XID_READ1
500         TX_TASK_INIT2   r3
501         clr     GRegs.tx.b.flags, GRegs.tx.b.flags, f_next_dma
503 tx_eof_on_deck_done:
504         TM_YIELD
505         flip_tx_r0_r23
506         add     GRegs.pkt_cnt.w.tx, GRegs.pkt_cnt.w.tx, 1
507         loop_here
509 no_new_tx_10mbps:
510         ldi     GRegs.tx_blk, 0
511         clr     GRegs.speed_f, GRegs.speed_f, f_col_detected
512         clr     GRegs.speed_f, GRegs.speed_f, f_stopped_due_col
513         ldi     GRegs.ret_cnt, 0
514         start_ipg_timer 
516 no_new_tx:
517         ldi     GRegs.tx.b.state, TX_S_IDLE
518         qba     tx_eof_on_deck_done
520 ; we came here due to collision, so we are in half duplex mode.
521 ; We either retranssmit or drop the packet
522 ;  
523 tx_proc_col:
524         m_inc_stat      r1.b0, TX_COL_RETRIES
525         qble    txp_max_retry, GRegs.ret_cnt, 16 ; todo: define
526         qblt    txp_max_retry, GRegs.tx_blk, 2   ; TODO: update for late col
527         start_backoff_timer GRegs.ret_cnt
528         add     GRegs.ret_cnt, GRegs.ret_cnt, 1
529         qba     no_new_tx 
530 txp_max_retry:
531         m_inc_stat      r1.b0, TX_COL_DROPPED
532         qbbs    txp_max_01, GRegs.tx.b.flags, f_next_dma        
533         SPIN_TOG_LOCK_LOC PRU_RTU_EOD_P_FLAG
534         qba     txp_max_02
535 txp_max_01:
536         SPIN_TOG_LOCK_LOC PRU_RTU_EOD_E_FLAG
537 txp_max_02:
538         start_ipg_timer
539         ldi     GRegs.ret_cnt, 0
540         qbbc    no_new_tx_10mbps, GRegs.speed_f, f_100mbps
541         qba     no_new_tx
542         
543 ;------exception cases------
544 tx_underflow:
545         ldi     GRegs.tx.b.state, TX_S_ERR
546         TM_YIELD
547         add     GRegs.pkt_cnt.w.tx, GRegs.pkt_cnt.w.tx, 1
548         loop_here
550 ;---------------------------------------------------------------------
551 ;  ENd TX_EOF
552 ;----------------------------------------------------------------------
554 ;---------------------------------------------------------------------
555 ; TX_FIFO  EVENT {{{1
556 ;----------------------------------------------------------------------
557 TX_FIFO:
558         qbeq    handle_portq, GRegs.tx.b.state, TX_S_ACTIVE
559         TM_YIELD
560         loop_here
562 handle_portq:
563         flip_tx_r0_r23
564         add     GRegs.tx_blk, GRegs.tx_blk, 1
565         qbbs    tx_fifo1, GRegs.speed_f, f_half_d
566         qbbs    txf_90, GRegs.speed_f, f_stopped_due_col ; don't stop twice
567         
568         update_col_status
569         qbbc    tx_fifo1, GRegs.speed_f, f_col_detected
570         ; collision was detected, we need to stop pushing to TXL2
571         stop_tx_due_colission
572         qba     txf_90
574 tx_fifo1:
575         TX_FILL_FIFO    XFR2VBUS_XID_READ0
576 txf_90: TM_YIELD
577         flip_tx_r0_r23
578         loop_here
580 ;-------------------------------------------------------------------------
581 ;RXTX_ERR EVENT  ; {{{1
582 ; assume rx issue.
583 ; reset rxl2 fifo
584 ; hopefully that cleans things up
585 ;  need to see what else needs to be done
586 RXTX_ERR:
587         flip_tx_r0_r23
588         qbne    rx_err?, GRegs.tx.b.state, TX_S_ERR
589         ; wait DMA ir complete
590         qbbs    $3, TxRegs.ds_flags, 4
591 $1:     xin     XFR2VBUS_XID_READ0, &r18, 4
592         qbeq    $2, r18.w0, 0x5
593         qbeq    $2, r18, 0
594         qba     $1
595 $2:     nop
596         XFR2VBUS_CANCEL_READ_AUTO_64_CMD XFR2VBUS_XID_READ0
597         nop
598         XFR2VBUS_READ64_RESULT XFR2VBUS_XID_READ0
599         SPIN_SET_LOCK_LOC PRU_RTU_EOD_P_FLAG
600         SPIN_CLR_LOCK_LOC PRU_RTU_EOD_P_FLAG
601         jmp     $5
602 $3:     xin     XFR2VBUS_XID_READ1, &r18, 4
603         qbeq    $4, r18.w0, 0x5
604         qbeq    $4, r18, 0
605         qba     $3
606 $4:     nop
607         XFR2VBUS_CANCEL_READ_AUTO_64_CMD XFR2VBUS_XID_READ1
608         nop
609         XFR2VBUS_READ64_RESULT XFR2VBUS_XID_READ1
610         SPIN_SET_LOCK_LOC PRU_RTU_EOD_E_FLAG
611         SPIN_CLR_LOCK_LOC PRU_RTU_EOD_E_FLAG
612 $5:
613         set     r31.t30; TX_RESET
614         nop
615         nop
616         ;set TX to TX_S_IDLE
617         ldi     GRegs.tx.b.state, TX_S_IDLE
618         qba     rxtx_err_exit
619 rx_err?
620         ldi     r11.b3, 0x80
621         xout    22, &r11, 4
622         set     r31.t22  ; clear rx eof  (why isnt it bit 20?)
623         ldi     r7, 1  ;indicate we drop
624 ;for now assume it is the RXL1 overflowing for next frame
625 ;todo: how to check to see if it is for this frame??
626         ldi     GRegs.rx.b.state, RX_STATE_OVER0
627 rxtx_err_exit:
628         TM_YIELD
629         flip_tx_r0_r23
630         loop_here
632 ;-------------------------------------------------------------------------
633 ; Dummy: TX_NOP {{{1
634 ;-------------------------------------------------------------------------
635 TX_NOP:
636         TM_YIELD
637         loop_here
638 ;----------------------------------------------------------------------
639 ; Dummy: END TX_NOP
640 ;-------------------------------------------------------------------------
642 ;---------------------------------------------------------------
643 ; RX TASK, State 1:  RX  SOF {{{1
644 ;--------------------------------------------------------------
645 RX_SOF:
646 ;turn off RX_SOF
647         TM_YIELD
648         loop_here
649 ;---------------------------------------------------------------
650 ; END RX TASK, State 1
651 ;--------------------------------------------------------------
653 NBTR    .set    32
654 ;---------------------------------------------------------------
655 ; RX TASK, State 2: RX_B0 {{{1
656 ;--------------------------------------------------------------
657 RX_B0:
658         flip_rx_r0_r23
660 ;BRING IN THE DATA
661         xin     RXL2_BANK0, &r2, NBTR
662         ldi     RxRegs.aux_flags, 1
663         qbeq    rxb0_already_over, GRegs.rx.b.state, RX_STATE_OVER0
665         ldi     GRegs.rx.x, 0x180 ;fresh state=1, (sof flag set)
666         P_W32_S rxb0_full  ;stash pkt bytes in bs slot but don't start
668         jmp     rx_b0_done
670 ;some error/exception cases handling here
671 rxb0_full:  ;psi fifo in bsram full
672         P_W32_ABORT
673         ldi     GRegs.rx.x, 0x7F80
674         add     GRegs.snf.b.dbg_cnt, GRegs.snf.b.dbg_cnt, 1
675         jmp     rx_b0_done
677 rxb0_already_over:
678         ldi     GRegs.rx.x, 0x7F80
679 ;todo: bump stats
681 rx_b0_done:
682         TM_YIELD
683         flip_rx_r0_r23
684         add     GRegs.rx.b.pkt_len, GRegs.rx.b.pkt_len, 32 ;hopefully this gets executed!!
685         loop_here
686 ;---------------------------------------------------------------
687 ; END RX TASK, State 2
688 ;--------------------------------------------------------------
690 ;---------------------------------------------------------------
691 ; RX TASK, State 3: RX_B1 {{{1
692 ;--------------------------------------------------------------
693 RX_B1:
694         flip_rx_r0_r23
695         qbeq    skip_b1, GRegs.rx.b.state, RX_STATE_DROP
696 ;!!better be here!!
697 ;r5.b0 = route info
698 ;r5.b1 = fid
699 ;r5.w2 = index
700 ;r6 = buffer ptr for s&f
701         ldi     r0.b1, 0
702 stall_loop:
703         PRU_IPC_RX_CH1
704         qbbs    got_ipc, r5.b0, f_rx_sof
705         add     r0.b1, r0.b1, 1
706         qbne    stall_loop, r0.b1, RB1_STALL_LIMIT
707         ldi     GRegs.rx.b.state, RX_STATE_DROP ;stall limit reached
708         jmp     rb1_ipc_done
709 got_ipc:
710         mov     GRegs.rx.b.flags, r5.b0 ;forwarding info we got from RTU
711         PRU_IPC_RX_CH1_CLRB7    ;clear bit so we know we got it
712         mov     RxRegs.pq_cur, r6 ;save buffer pointer (may not use)  ;=flow in MAC
714 rb1_ipc_done:
715         xin     RXL2_BANK1, &r2, 32 ;bring in data (r2-r9)
716         clr     RxRegs.aux_flags, RxRegs.aux_flags, f_fh
717         set     RxRegs.aux_flags, RxRegs.aux_flags, f_b1_seen
719         TM_DISABLE
720         qbbc    b1_rx_path1a, GRegs.rx.b.flags, f_tohost
721         P_W32   rxb1_full  ;stash pkt bytes in bs slot
722         jmp     rx_b1_done
723 rxb1_full:
724         ldi     GRegs.rx.x, 0x7F80
725         add     GRegs.snf.b.dbg_cnt, GRegs.snf.b.dbg_cnt,1
726 b1_rx_path1a:
727         P_W32_ABORT ;abort the stashing of pkt in BS (for PSI)
728 rx_b1_done:
729         TM_ENABLE
730 b1_exit:TM_YIELD
731         flip_rx_r0_r23
732         add     GRegs.rx.b.pkt_len, GRegs.rx.b.pkt_len, 32
733         loop_here
735 skip_b1:xin     RXL2_BANK1, &r2, 32  ;error case. just read in data and drop
736         clr     RxRegs.aux_flags, RxRegs.aux_flags, f_fh
737         jmp     b1_exit
738 ;---------------------------------------------------------------
739 ; END RX TASK, State 3
740 ;--------------------------------------------------------------
742 ;---------------------------------------------------------------
743 ; RX TASK, State 4: RX_BN {{{1
744 ;--------------------------------------------------------------
745 RX_BN:
746         flip_rx_r0_r23
747 ;check for overflow/drop or pkt too long
748         qbne    pkt_ok, GRegs.rx.b.state, RX_STATE_DROP
749 ;errors:
750         ldi     GRegs.rx.x, 0x7f80  ;indicate we need to drop
751         qbbs    rx_bnerr_sideB, RxRegs.aux_flags, f_fh
752 ;side A
753         xin     RXL2_BANK0, &r2, 32
754         jmp     rx_bn_done
755 rx_bnerr_sideB:
756 ;side B
757         xin     RXL2_BANK1, &r2, 32
758         jmp     rx_bn_done
759 rxbn_full:
760         ldi     GRegs.rx.x, 0x7f80  ;indicate we need to drop
761         P_W32_ABORT
762         add     GRegs.snf.b.dbg_cnt, GRegs.snf.b.dbg_cnt,1
763         jmp     rx_bn_done
765 ;take pkt, all good
766 pkt_ok: qbbs    rx_bn_sideB, RxRegs.aux_flags, f_fh
767         xin     RXL2_BANK0, &r2, 32
768         set     RxRegs.aux_flags, RxRegs.aux_flags, f_fh
769         jmp     bn_cont1
770 rx_bn_sideB:
771         xin     RXL2_BANK1, &r2, 32
772         clr     RxRegs.aux_flags, RxRegs.aux_flags, f_fh
773 bn_cont1:
774         qbbc    rx_bn_done, GRegs.rx.x, 0
775         P_W32   rxbn_full
776 rx_bn_done:
777         TM_YIELD
778         flip_rx_r0_r23
779         add     GRegs.rx.b.pkt_len, GRegs.rx.b.pkt_len, 32
780         loop_here
781 ;---------------------------------------------------------------
782 ; END RX TASK, State 4
783 ;--------------------------------------------------------------
785 ;---------------------------------------------------------------
786 ; RX TASK, State 5: RX_EOF {{{1
787 ;--------------------------------------------------------------
788 RX_EOF:
789         TM_DISABLE
790         flip_rx_r0_r23
791         qbeq    no_rx_sof, GRegs.rx.b.state, RX_STATE_DROP
792         qbbc    no_rx_sof, GRegs.rx.b.flags, f_rx_sof
793         ldi     r0.w0, 0x3310
794         and     r0.w0, r31.w2, r0.w0
795         qbne    beof_rx_err, r0.b0, 0x10 ;check for rx errors
796         qbbs    rx_beof_sideB, RxRegs.aux_flags, f_fh
798 ;side A, r18 and r0.b0  has length
799         RX_EOF_RCV_BANK0
800         ldi     r11.b3, 0x80
801         xout    22, &r11, 4
802         set     r31.t22 ; clear rx eof  (why isnt it bit 20?)
803         mov     RxRegs.res1, r0.b0
804         jmp     rx_beof_cont0
806 rx_beof_sideB:
807 ;side B, r18 and r0.b0  has length
808         RX_EOF_RCV_BANK1
809         ldi     r11.b3, 0x80
810         xout    22, &r11, 4
811         set     r31.t22 ; clear rx eof  (why isnt it bit 20?)
812         add     RxRegs.res1, r0.b0, 32
814 rx_beof_cont0:
815         add     GRegs.rx.b.pkt_len, GRegs.rx.b.pkt_len, r0.b0
816         qbbc    rx_eof_done, GRegs.rx.b.flags, f_tohost
817 ;check for pkt to long
818         qbge    th_pkt_ok, GRegs.rx.b.pkt_len, r30.w0
819         add     r30.w2, r30.w2,1   ; max error (like crc)
820         P_W32_ABORT
821         jmp     rx_eof_done
822 th_pkt_ok:
823 ; push 32 to bsram fifo (not all will be valid)
824         P_W32   rxeof_noroom
825 ; push 'descriptor' to local queue. will be popped by bg task
826         mov     r2.w2, RxRegs.pq_cur       ;flow
827         mov     r2.w0, GRegs.rx.b.pkt_len
828         mov     r3, GRegs.snf.x      ;bsram fifo position (maybe not necessary)
829 ;to do add rxtx timestamp
830         PSIQ_PUSH       rxeof_qfull
832 rx_eof_done:
833         ; check for runt packet
834         qble    rx_eof_done_b, GRegs.rx.b.pkt_len, 64
835         set     r31.t18         ;reset RX_fifo
837 rx_eof_done_b:
838         TM_ENABLE
839         flip_rx_r0_r23
840         TM_YIELD
841         ldi     GRegs.rx.s.fl_n_state, 0
842         add     GRegs.pkt_cnt.w.rx, GRegs.pkt_cnt.w.rx, 1 ;also should tell bg #of pkts we have procesed
843         loop_here
845 ;----------------------------
846 ; bad frame, error handling
847 ;-----------------------------
848 rxeof_noroom:
849 rxeof_qfull:
850         P_W32_ABORT
851         add     GRegs.snf.b.dbg_cnt, GRegs.snf.b.dbg_cnt,1
852         jmp     rx_eof_done
854 beof_rx_err:
855 no_rx_sof:
856 ;saw no sof before eof or other such issues
857         ldi     r11.b3, 0x80
858         xout    22, &r11, 4
859         set     r31, r31, 22 ; clear rx eof  (why isnt it bit 20?)
860         jmp rx_eof_done
861 ;---------------------------------------------------------------
862 ; END RX TASK, State 5
863 ;--------------------------------------------------------------
865  .include "resource_table.h"