[processor-sdk/pdk.git] / packages / ti / drv / icss_emac / firmware / icss_dualemac / src / emac_MII_Rcv.asm
diff --git a/packages/ti/drv/icss_emac/firmware/icss_dualemac/src/emac_MII_Rcv.asm b/packages/ti/drv/icss_emac/firmware/icss_dualemac/src/emac_MII_Rcv.asm
index ef1eef5a79df8b905d2ca6fa700502b9c3696b22..6b8651257d50d6359e93cf59c6297b245ec04199 100755 (executable)
.global XMT_QUEUE
.global TASK_EXECUTION_FINISHED
.global FN_TIMESTAMP_GPTP_PACKET
- .global FN_TIMESTAMP_GPTP_PACKET_UDP
+ .global FN_CHECK_AND_CLR_PTP_FWD_FLAG
+ .global FN_CHECK_AND_CLR_PTP_FWD_FLAG_L2
.global FN_COMPARE_DELAY_RESP_ID
FB_SKIP_VLAN_FLTR:
.endif
+
+ ;PINDSW-4577: Fix to avoid cut-through packets from going via Storm Prevention
+ ;Storm prevention is done only if host receive flag is set
+ QBBC FB_CONT_CT_CHECK, MII_RCV.rx_flags , host_rcv_flag_shift
; Storm Prevention
QBBC FB_STORM_NOT_MC, R22, RX_MC_FRAME
LDI RCV_TEMP_REG_3.w2, PTP_IPV4_UDP_E2E_ENABLE
LBCO &RCV_TEMP_REG_3.b2, ICSS_SHARED_CONST, RCV_TEMP_REG_3.w2, 1
QBEQ PTP_NOT_ENABLED_RX_B2, RCV_TEMP_REG_3.b2, 0
- JAL R11.w2, FN_TIMESTAMP_GPTP_PACKET_UDP
+ QBBC PTP_NOT_ENABLED_RX_B2, R22, RX_IS_UDP_PTP_BIT
+ CLR R22, R22, RX_IS_UDP_PTP_BIT
+ JAL RCV_TEMP_REG_3.w2, FN_TIMESTAMP_GPTP_PACKET
+ JAL RCV_TEMP_REG_3.w2, FN_CHECK_AND_CLR_PTP_FWD_FLAG
PTP_NOT_ENABLED_RX_B2:
.endif ; "PTP"
QBA EXIT_PREPROCESSING_NB
LESS_THAN_32_BYTES_RCVD:
.if $defined(PTP)
+ ;we don't want to execute this for UDP frames, since this will be executed again later
+ QBBS PTP_SKIP_EARLY_TS_FOR_UDP_1, R22, RX_IS_UDP_PTP_BIT
+ JAL RCV_TEMP_REG_3.w2, FN_CHECK_AND_CLR_PTP_FWD_FLAG_L2
JAL RCV_TEMP_REG_3.w2, FN_TIMESTAMP_GPTP_PACKET
-
- .if $defined("ICSS_DUAL_EMAC_BUILD")
- ; For DualEMAC, check here to skip host rcv to properly drop sync frames not from master
- QBBC NB_PROCESS_32BYTES_CHECK_FLAGS_QUEUE_NOT_FULL, MII_RCV.rx_flags, host_rcv_flag_shift ; MII_RCV.rx_flags.host_rcv_flag
- .endif
-
- LDI RCV_TEMP_REG_3.w2, PTP_IPV4_UDP_E2E_ENABLE
- LBCO &RCV_TEMP_REG_3.b2, ICSS_SHARED_CONST, RCV_TEMP_REG_3.w2, 1
- QBEQ PTP_NOT_ENABLED_RX_B1, RCV_TEMP_REG_3.b2, 0
- M_GPTP_CHECK_AND_SET_FLAGS_L4
-PTP_NOT_ENABLED_RX_B1:
+PTP_SKIP_EARLY_TS_FOR_UDP_1:
.endif ;PTP
EXIT_PREPROCESSING_NB:
.if $defined("PTP")
LDI RCV_TEMP_REG_1.w0, PTP_IPV4_UDP_E2E_ENABLE
LBCO &RCV_TEMP_REG_1.b0, ICSS_SHARED_CONST, RCV_TEMP_REG_1.w0, 1
- QBEQ PTP_NOT_ENABLED_RX_LB, RCV_TEMP_REG_1.b0, 0
- JAL R11.w2, FN_TIMESTAMP_GPTP_PACKET_UDP
+ QBEQ PTP_NOT_ENABLED_RX_LB, RCV_TEMP_REG_1.b0, 0
+ QBBC PTP_NOT_ENABLED_RX_LB, R22, RX_IS_UDP_PTP_BIT
+ CLR R22, R22, RX_IS_UDP_PTP_BIT
+ JAL RCV_TEMP_REG_3.w2, FN_TIMESTAMP_GPTP_PACKET
+ JAL RCV_TEMP_REG_3.w2, FN_CHECK_AND_CLR_PTP_FWD_FLAG
PTP_NOT_ENABLED_RX_LB:
.endif ; "PTP"
.if $defined(PTP)
ADD RCV_TEMP_REG_3.w2, MII_RCV.byte_cntr, 32
QBLT MORE_THAN_32_BYTES_RCVD, RCV_TEMP_REG_3.w2, 32
+
+ ;we don't want to execute this for UDP frames, since this will be executed again later
+ QBBS MORE_THAN_32_BYTES_RCVD, R22, RX_IS_UDP_PTP_BIT
+ JAL RCV_TEMP_REG_3.w2, FN_CHECK_AND_CLR_PTP_FWD_FLAG_L2
JAL RCV_TEMP_REG_3.w2, FN_TIMESTAMP_GPTP_PACKET
MORE_THAN_32_BYTES_RCVD:
.endif
SBCO &Ethernet, L3_OCMC_RAM_CONST, MII_RCV.buffer_index, b1
- ADD MII_RCV.byte_cntr, MII_RCV.byte_cntr, R0.b1 ; increment the count by R1 bytes
- QBGE LB_PROCESS_CHECK_FWD_FLAG, R0.b1, 4
+ ADD MII_RCV.byte_cntr, MII_RCV.byte_cntr, R0.b1 ; increment the count by R1 bytes
+ QBGE LB_PROCESS_CHECK_FWD_FLAG, R0.b1, 4 ;If only CRC is left to store then skip
QBNE RCV_LB_NO_QUEUE_WRAP_2, MII_RCV.wrkng_wr_ptr, MII_RCV.top_most_buffer_desc_offset
- AND MII_RCV.wrkng_wr_ptr , MII_RCV.base_buffer_desc_offset , MII_RCV.base_buffer_desc_offset
+ AND MII_RCV.wrkng_wr_ptr , MII_RCV.base_buffer_desc_offset , MII_RCV.base_buffer_desc_offset
QBA RCV_LB_QUEUE_WRAPPED_2
RCV_LB_NO_QUEUE_WRAP_2:
ADD MII_RCV.wrkng_wr_ptr, MII_RCV.wrkng_wr_ptr, 4
RCV_LB_QUEUE_WRAPPED_2:
QBA RCV_LB_CHECK_OVERFLOW
RCV_LB_APPEND_TS:
- ;Logic to append 10 bytes timestamp to the end of packet
-
-
+ ;--------------Logic to append 10 bytes timestamp to the end of packet----------
.if $defined("ICSS_SWITCH_BUILD")
QBBC LB_PROCESS_CHECK_FWD_FLAG, MII_RCV.rx_flags, host_rcv_flag_shift ;MII_RCV.rx_flags.host_rcv_flag
.endif
- ;check if entire timestamp goes into new block
- QBEQ LB_TS_IN_NEW_32B, R0.b1, 0
- ;check if we adding TS results in more than 32B
- ADD R1.b0, R0.b1, 8 ;Get the register offset
- ADD R0.b1, R0.b1, 10
- ;Data fits
-
- .if $defined(PTP)
- M_GPTP_LOAD_TS_OFFSET
- .endif
- LBCO &R10, ICSS_SHARED_CONST, RCV_TEMP_REG_1.w0, 10 ;TS in R19-R21.w0
-
- ;Copy timestamp to correct offset in R2-R9 bank.
- ;This copy might overwrite R10-R11 but we don't care, as it saves cycles!
- MVID *R1.b0++, R10
- MVID *R1.b0++, R11
- MVIW *R1.b0, R12.w0
- SBCO &Ethernet, L3_OCMC_RAM_CONST, MII_RCV.buffer_index, 32 ;Store data + timestamp
+ ;If there are 0 bytes to store then append timestamp in new block
+ QBEQ LB_TS_STORE_TS, R0.b1, 0
+ ADD MII_RCV.byte_cntr, MII_RCV.byte_cntr, R0.b1 ; increment the count by b1 bytes
+ QBGE LB_TS_STORE_TS, R0.b1, 4 ;If only CRC is left to store then skip and append TS
- QBLT LB_TS_DOES_NOT_FIT, R0.b1, 32
- ADD MII_RCV.byte_cntr, MII_RCV.byte_cntr, R0.b1 ; increment the count by R1 bytes
- QBA RCV_LB_CHECK_WRAPAROUND
+ SBCO &Ethernet, L3_OCMC_RAM_CONST, MII_RCV.buffer_index, b1 ;Store the data
-LB_TS_DOES_NOT_FIT:
- ; Compare current wrk pointer to top_most queue desc pointer ..check for wrap around
- QBNE LB_TS_DOES_NOT_FIT_NO_WRAP, MII_RCV.wrkng_wr_ptr, MII_RCV.top_most_buffer_desc_offset
+ ;Compare current wrk pointer to top_most queue desc pointer ..check for wrap around
+ QBNE LB_TS_NO_WRAP_1, MII_RCV.wrkng_wr_ptr, MII_RCV.top_most_buffer_desc_offset
AND MII_RCV.wrkng_wr_ptr , MII_RCV.base_buffer_desc_offset , MII_RCV.base_buffer_desc_offset
AND MII_RCV.buffer_index , MII_RCV.base_buffer_index , MII_RCV.base_buffer_index
- QBA LB_TS_DOES_NOT_FIT_STORE_REST
-LB_TS_DOES_NOT_FIT_NO_WRAP:
+ QBA LB_TS_STORE_TS
+LB_TS_NO_WRAP_1:
ADD MII_RCV.buffer_index, MII_RCV.buffer_index, 32
ADD MII_RCV.wrkng_wr_ptr, MII_RCV.wrkng_wr_ptr, 4
-LB_TS_DOES_NOT_FIT_STORE_REST: ;store rest of the bytes
-
- ;Need to store remaining bytes
- RSB R0.b2, R0.b1, 42 ;How many bytes of timestamp already appended in previous block ?
- ADD RCV_TEMP_REG_1.w0, RCV_TEMP_REG_1.w0, R0.b2 ;timestamp offset is already in RCV_TEMP_REG_1.w0
- LBCO &Ethernet, ICSS_SHARED_CONST, RCV_TEMP_REG_1.w0, 10
- SBCO &Ethernet, L3_OCMC_RAM_CONST, MII_RCV.buffer_index, 10
- ADD MII_RCV.byte_cntr, MII_RCV.byte_cntr, 10
- SUB MII_RCV.byte_cntr, MII_RCV.byte_cntr, R0.b2 ;Increment the byte counter with number of bytes actually saved in this 32B block
- QBA RCV_LB_CHECK_WRAPAROUND
+LB_TS_STORE_TS: ;store timestamp in new 32B block
-LB_TS_IN_NEW_32B: ;Timestamp goes into new 32B block
+ ;Load offset
.if $defined(PTP)
M_GPTP_LOAD_TS_OFFSET
.endif
- LBCO &Ethernet, ICSS_SHARED_CONST, RCV_TEMP_REG_1.w0, 10
- SBCO &Ethernet, L3_OCMC_RAM_CONST, MII_RCV.buffer_index, 10
- ADD MII_RCV.byte_cntr, MII_RCV.byte_cntr, 10
-
-RCV_LB_CHECK_WRAPAROUND:
+ ;Load the TS from Shared RAM
+ LBCO &R10, ICSS_SHARED_CONST, RCV_TEMP_REG_1.w0, 10
+ ;Store into L3 OCMC
+ SBCO &R10, L3_OCMC_RAM_CONST, MII_RCV.buffer_index, 10
+
;check wraparound
- QBNE RCV_LB_NO_QUEUE_WRAP_3, MII_RCV.wrkng_wr_ptr, MII_RCV.top_most_buffer_desc_offset
+ QBNE LB_TS_NO_WRAP_2, MII_RCV.wrkng_wr_ptr, MII_RCV.top_most_buffer_desc_offset
AND MII_RCV.wrkng_wr_ptr , MII_RCV.base_buffer_desc_offset , MII_RCV.base_buffer_desc_offset
QBA RCV_LB_CHECK_OVERFLOW
-RCV_LB_NO_QUEUE_WRAP_3:
+LB_TS_NO_WRAP_2:
ADD MII_RCV.wrkng_wr_ptr, MII_RCV.wrkng_wr_ptr, 4
RCV_LB_CHECK_OVERFLOW:
JMP LB_RELEASE_QUEUE ; Clear the EOF and other possible error flags.
LB_NO_RX_FRAME_ERROR:
-
- .if $defined(PTP)
- QBBS LB_RELEASE_HOST_QUEUE, R22, PTP_RELEASE_HOST_QUEUE_BIT
-
-PTP_HOST_QUEUE_RELEASE_DONE:
- .endif ;PTP
.if $defined("ICSS_SWITCH_BUILD")
- .if $defined(PTP)
+ .if $defined(PTP)
+ ;This code is used to control PTP packet forwarding from driver, if mem location
+ ;is set to 1 then FW skips the flow. By default (0) flow is taken
+ LBCO &RCV_TEMP_REG_2.b0, ICSS_SHARED_CONST, DISABLE_PTP_FRAME_FORWARDING_CTRL_OFFSET, 1
+ QBEQ PTP_PORT_QUEUE_RELEASE_DONE, RCV_TEMP_REG_2.b0, 1
QBBS LB_RELEASE_PORT_QUEUE, R22, PTP_RELEASE_PORT_QUEUE_BIT
PTP_PORT_QUEUE_RELEASE_DONE:
.endif ;TWO_PORT_CFG
; clear length field (18..28) and update length with current received frame
LDI RCV_TEMP_REG_2.w0, 0
- MOV RCV_TEMP_REG_2.w2, RCV_CONTEXT.byte_cntr ;assign packet length
- .if $defined(PTP)
- QBBS LB_SKIP_CRC_SUBTRACT, R22, RX_IS_PTP_BIT ;skip CRC subtraction for PTP frames (so driver can see the Rx timestamp)
- .endif ;PTP
- SUB RCV_TEMP_REG_2.w2, RCV_TEMP_REG_2.w2, 4 ;4 byte of FCS
-LB_SKIP_CRC_SUBTRACT:
+ SUB RCV_TEMP_REG_2.w2, RCV_CONTEXT.byte_cntr, 4 ;4 byte of FCS
LSL RCV_TEMP_REG_2.w2, RCV_TEMP_REG_2.w2, 2
;Set the Port number on which packet was received
.endif
CLR RCV_TEMP_REG_2, RCV_TEMP_REG_2, 15 ;Clear PTP descriptor bit
- .if $defined(PTP)
+
+ .if $defined(PTP) ;check if bit 15 needs to be set
QBBC LB_SKIP_PTP_DESC_BIT_SET, R22, RX_IS_PTP_BIT
CLR R22, R22, RX_IS_PTP_BIT
SET RCV_TEMP_REG_2 , RCV_TEMP_REG_2 , 15 ;Indicate to the driver that this is a PTP frame
SBCO &RCV_TEMP_REG_2, ICSS_SHARED_CONST, RCV_TEMP_REG_1.w0, 4
.endif ;TWO_PORT_CFG
.endif
- .if $defined(PTP)
- QBBC LB_RELEASE_QUEUE_CHECK_FWD_FLAG, R22, PTP_RELEASE_HOST_QUEUE_BIT
- CLR R22, R22, PTP_RELEASE_HOST_QUEUE_BIT
- QBA PTP_HOST_QUEUE_RELEASE_DONE
- .endif
-
+
LB_RELEASE_QUEUE_CHECK_FWD_FLAG:
.if $defined("ICSS_SWITCH_BUILD")
QBBS LB_RELEASE_PORT_QUEUE, MII_RCV.rx_flags_extended, port_queue_overflow_shift ;MII_RCV.rx_flags_extended.port_queue_overflow
.if $defined(PTP)
QBBC LB_RELEASE_QUEUE_CHECK_DONE, R22, PTP_RELEASE_PORT_QUEUE_BIT
CLR R22, R22, PTP_RELEASE_PORT_QUEUE_BIT
+ CLR MII_RCV.rx_flags, MII_RCV.rx_flags, fwd_flag_shift
QBA PTP_PORT_QUEUE_RELEASE_DONE
.endif
LB_RELEASE_QUEUE_CHECK_DONE: