@@ -638,30 +638,37 @@ void drop_optional_header_fields( hls::stream<optionalFieldsMeta>& metaIn,
638638 * kind | length | description
639639 * 0 | 1B | End of options list
640640 * 1 | 1B | NOP/Padding
641- * 2 | 4B | MSS (Maximum segment size)
641+ * 2 | 4B | MSS (Maximum segment size) - If omitted, 536B for IPv4
642642 * 3 | 3B | Window scale
643643 * 4 | 2B | SACK permitted (Selective Acknowledgment)
644644 */
645645void parse_optional_header_fields ( hls::stream<ap_uint<4 > >& dataOffsetIn,
646646 hls::stream<ap_uint<320 > >& optionalHeaderFieldsIn,
647- hls::stream<ap_uint<4 > >& windowScaleOut)
647+ hls::stream<ap_uint<4 > >& windowScaleOut,
648+ hls::stream<ap_uint<16 > >& mssOut)
648649{
649650 #pragma HLS PIPELINE II=1
650651 #pragma HLS INLINE off
651652
652653 enum fsmStateType {IDLE, PARSE};
653654 static fsmStateType state = IDLE;
654- static ap_uint<4 > dataOffset;
655+ static ap_uint<4 > dataOffsetDword;
656+ static ap_uint<6 > dataOffsetByte;
655657 static ap_uint<320 > fields;
658+ static bool got_ws = false ;
659+ static bool got_mss = false ;
656660
657661 switch (state)
658662 {
659663 case IDLE:
660664 if (!dataOffsetIn.empty () && !optionalHeaderFieldsIn.empty ())
661665 {
662666 // std::cout << "PARSE IDLE" << std::endl;
663- dataOffsetIn.read (dataOffset);
667+ dataOffsetIn.read (dataOffsetDword);
668+ dataOffsetByte = 4 * (ap_int<6 >)dataOffsetDword;
664669 optionalHeaderFieldsIn.read (fields);
670+ got_ws = false ;
671+ got_mss = false ;
665672 state = PARSE;
666673 }
667674 break ;
@@ -671,35 +678,64 @@ void parse_optional_header_fields( hls::stream<ap_uint<4> >& dataOffsetIn,
671678
672679 switch (optionKind)
673680 {
674- case 0 : // End of option list
675- windowScaleOut.write (0 );
681+ case 0 :{// End of option list
682+ if (!got_mss) mssOut.write (536 );
683+ if (!got_ws) windowScaleOut.write (0 );
676684 // std::cout << "PARSE EOL" << std::endl;
677685 state = IDLE;
678686 break ;
679- case 1 :
680- optionLength = 1 ;
687+ }
688+ case 1 :{ // NOP
689+ if (dataOffsetByte == 1 ){
690+ if (!got_mss) mssOut.write (536 );
691+ if (!got_ws) windowScaleOut.write (0 );
692+ state = IDLE;
693+ }
694+ else optionLength = 1 ;
681695 break ;
682- case 3 :
696+ }
697+ case 2 :{
698+ ap_uint<16 > mss;
699+ mss (15 ,8 ) = fields (23 ,16 );
700+ mss ( 7 ,0 ) = fields (31 ,24 );
701+ mssOut.write (mss);
702+ if (dataOffsetByte == 4 || got_ws){
703+ if (!got_ws) windowScaleOut.write (0 );
704+ state = IDLE;
705+ }
706+ got_mss = true ;
707+ optionLength = 4 ;
708+ break ;
709+ }
710+ case 3 :{
683711 // std::cout << "PARSE WS: " << (uint16_t)fields(19, 16) << std::endl;
684712 windowScaleOut.write (fields (19 , 16 ));
685- state = IDLE;
713+ if (dataOffsetByte == 3 || got_mss){
714+ if (!got_mss) mssOut.write ((ap_uint<16 >)536 );
715+ state = IDLE;
716+ }
717+ optionLength = 3 ;
718+ got_ws = true ;
686719 break ;
687- default :
688- if (dataOffset == optionLength)
689- {
690- windowScaleOut.write (0 );
720+ }
721+ default :{
722+ if (dataOffsetByte == optionLength){
723+ if (!got_mss) mssOut.write ((ap_uint<16 >)536 );
724+ if (!got_ws) windowScaleOut.write (0 );
691725 // std::cout << "PARSE DONE" << std::endl;
692726 state = IDLE;
693727 }
694728 break ;
729+ }
695730 }// switch
696- dataOffset -= optionLength;
731+ dataOffsetByte -= optionLength;
697732 fields = (fields >> (optionLength*8 ));
698733 break ;
699734 }// switch
700735}
701736
702737void merge_header_meta (hls::stream<ap_uint<4 > >& rxEng_winScaleFifo,
738+ hls::stream<ap_uint<16 > >& rxEng_mssFifo,
703739 hls::stream<rxEngineMetaData>& rxEng_headerMetaFifo,
704740 hls::stream<rxEngineMetaData>& rxEng_metaDataFifo)
705741{
@@ -723,15 +759,17 @@ void merge_header_meta(hls::stream<ap_uint<4> >& rxEng_winScaleFifo,
723759 else
724760 {
725761 meta.winScale = 0 ;
762+ meta.mss = 536 ;
726763 rxEng_metaDataFifo.write (meta);
727764 }
728765 }
729766 break ;
730767 case 1 :
731- if (!rxEng_winScaleFifo.empty ())
768+ if (!rxEng_winScaleFifo.empty () && !rxEng_mssFifo. empty () )
732769 {
733770 // std::cout << "META MERGE 1" << std::endl;
734771 meta.winScale = rxEng_winScaleFifo.read ();
772+ meta.mss = rxEng_mssFifo.read ();
735773 rxEng_metaDataFifo.write (meta);
736774 state = 0 ;
737775 }
@@ -1368,7 +1406,7 @@ void rxTcpFSM( stream<rxFsmMetaData>& fsmMetaDataFifo,
13681406 // Initialize rxSar, SEQ + phantom byte for recvd and head pointer, offset to 0, gap set to false
13691407 rxEng2rxSar_upd_req.write (rxSarRecvd (fsm_meta.sessionID , fsm_meta.meta .seqNumb +1 , fsm_meta.meta .seqNumb +1 , 0 , false , rx_win_shift));
13701408 // Initialize receive window
1371- rxEng2txSar_upd_req.write ((rxTxSarQuery (fsm_meta.sessionID , 0 , fsm_meta.meta .winSize , txSar.cong_window , 0 , false , tx_win_shift))); // TODO maybe include count check
1409+ rxEng2txSar_upd_req.write ((rxTxSarQuery (fsm_meta.sessionID , 0 , fsm_meta.meta .winSize , txSar.cong_window , 0 , false , tx_win_shift, fsm_meta. meta . mss ))); // TODO maybe include count check
13721410#else
13731411 // Initialize rxSar, SEQ + phantom byte, last '1' for makes sure appd is initialized
13741412 rxEng2rxSar_upd_req.write (rxSarRecvd (fsm_meta.sessionID , fsm_meta.meta .seqNumb +1 , fsm_meta.meta .seqNumb +1 , 0 , false , 1 ));
@@ -1432,7 +1470,7 @@ void rxTcpFSM( stream<rxFsmMetaData>& fsmMetaDataFifo,
14321470 ap_uint<4 > rx_win_shift = (fsm_meta.meta .winScale == 0 ) ? 0 : WINDOW_SCALE_BITS;
14331471 ap_uint<4 > tx_win_shift = fsm_meta.meta .winScale ;
14341472 rxEng2rxSar_upd_req.write (rxSarRecvd (fsm_meta.sessionID , fsm_meta.meta .seqNumb +1 , fsm_meta.meta .seqNumb +1 , 0 , false , rx_win_shift));
1435- rxEng2txSar_upd_req.write ((rxTxSarQuery (fsm_meta.sessionID , fsm_meta.meta .ackNumb , fsm_meta.meta .winSize , txSar.cong_window , 0 , false , tx_win_shift))); // TODO maybe include count check
1473+ rxEng2txSar_upd_req.write ((rxTxSarQuery (fsm_meta.sessionID , fsm_meta.meta .ackNumb , fsm_meta.meta .winSize , txSar.cong_window , 0 , false , tx_win_shift, fsm_meta. meta . mss ))); // TODO maybe include count check
14361474#else
14371475 // initialize rx_sar, SEQ + phantom byte, last '1' for appd init
14381476 rxEng2rxSar_upd_req.write (rxSarRecvd (fsm_meta.sessionID , fsm_meta.meta .seqNumb +1 , fsm_meta.meta .seqNumb +1 , 0 , false , 1 ));
@@ -2103,10 +2141,12 @@ void rx_engine( stream<net_axis<WIDTH> >& ipRxData,
21032141 static hls::stream<ap_uint<4 > > rxEng_dataOffsetFifo (" rxEng_dataOffsetFifo" );
21042142 static hls::stream<ap_uint<320 > > rxEng_optionalFieldsFifo (" rxEng_optionalFieldsFifo" );
21052143 static hls::stream<ap_uint<4 > > rxEng_winScaleFifo (" rxEng_winScaleFifo" );
2144+ static hls::stream<ap_uint<16 > > rxEng_mssFifo (" rxEng_mssFifo" );
21062145 #pragma HLS stream variable=rxEng_headerMetaFifo depth=16
21072146 #pragma HLS stream variable=rxEng_dataOffsetFifo depth=2
21082147 #pragma HLS stream variable=rxEng_optionalFieldsFifo depth=2
21092148 #pragma HLS stream variable=rxEng_winScaleFifo depth=2
2149+ #pragma HLS stream variable=rxEng_mssFifo depth=2
21102150 // TODO data pack
21112151#endif
21122152
@@ -2136,8 +2176,8 @@ void rx_engine( stream<net_axis<WIDTH> >& ipRxData,
21362176 // rxTcpInvalidDropper<WIDTH>(rxEng_dataBuffer3b, rxEng_tcpValidFifo, rxEng_dataBuffer3);
21372177
21382178#if (WINDOW_SCALE)
2139- parse_optional_header_fields (rxEng_dataOffsetFifo, rxEng_optionalFieldsFifo, rxEng_winScaleFifo);
2140- merge_header_meta (rxEng_winScaleFifo, rxEng_headerMetaFifo, rxEng_metaDataFifo);
2179+ parse_optional_header_fields (rxEng_dataOffsetFifo, rxEng_optionalFieldsFifo, rxEng_winScaleFifo, rxEng_mssFifo );
2180+ merge_header_meta (rxEng_winScaleFifo, rxEng_mssFifo, rxEng_headerMetaFifo, rxEng_metaDataFifo);
21412181#endif
21422182
21432183 rxMetadataHandler ( rxEng_metaDataFifo,
0 commit comments