@@ -979,6 +979,7 @@ static int sky2_rx_start(struct sky2_port *sky2)
979979 struct sky2_hw * hw = sky2 -> hw ;
980980 unsigned rxq = rxqaddr [sky2 -> port ];
981981 int i ;
982+ unsigned thresh ;
982983
983984 sky2 -> rx_put = sky2 -> rx_next = 0 ;
984985 sky2_qset (hw , rxq );
@@ -1003,9 +1004,21 @@ static int sky2_rx_start(struct sky2_port *sky2)
10031004 sky2_rx_add (sky2 , re -> mapaddr );
10041005 }
10051006
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+
10091022
10101023 /* Tell chip about available buffers */
10111024 sky2_write16 (hw , Y2_QADDR (rxq , PREF_UNIT_PUT_IDX ), sky2 -> rx_put );
0 commit comments