@@ -979,6 +979,7 @@ static int sky2_rx_start(struct sky2_port *sky2)
979
979
struct sky2_hw * hw = sky2 -> hw ;
980
980
unsigned rxq = rxqaddr [sky2 -> port ];
981
981
int i ;
982
+ unsigned thresh ;
982
983
983
984
sky2 -> rx_put = sky2 -> rx_next = 0 ;
984
985
sky2_qset (hw , rxq );
@@ -1003,9 +1004,21 @@ static int sky2_rx_start(struct sky2_port *sky2)
1003
1004
sky2_rx_add (sky2 , re -> mapaddr );
1004
1005
}
1005
1006
1006
- /* Truncate oversize frames */
1007
- sky2_write16 (hw , SK_REG (sky2 -> port , RX_GMF_TR_THR ), sky2 -> rx_bufsize - 8 );
1008
- sky2_write32 (hw , SK_REG (sky2 -> port , RX_GMF_CTRL_T ), RX_TRUNC_ON );
1007
+
1008
+ /*
1009
+ * The receiver hangs if it receives frames larger than the
1010
+ * packet buffer. As a workaround, truncate oversize frames, but
1011
+ * the register is limited to 9 bits, so if you do frames > 2052
1012
+ * you better get the MTU right!
1013
+ */
1014
+ thresh = (sky2 -> rx_bufsize - 8 ) / sizeof (u32 );
1015
+ if (thresh > 0x1ff )
1016
+ sky2_write32 (hw , SK_REG (sky2 -> port , RX_GMF_CTRL_T ), RX_TRUNC_OFF );
1017
+ else {
1018
+ sky2_write16 (hw , SK_REG (sky2 -> port , RX_GMF_TR_THR ), thresh );
1019
+ sky2_write32 (hw , SK_REG (sky2 -> port , RX_GMF_CTRL_T ), RX_TRUNC_ON );
1020
+ }
1021
+
1009
1022
1010
1023
/* Tell chip about available buffers */
1011
1024
sky2_write16 (hw , Y2_QADDR (rxq , PREF_UNIT_PUT_IDX ), sky2 -> rx_put );
0 commit comments