lan743x: Fix TX Stall Issue
It has been observed that tx queue stalls while downloading
from certain web sites (example www.speedtest.net)
The cause has been tracked down to a corner case where
dma descriptors where not setup properly. And there for a tx
completion interrupt was not signaled.
This fix corrects the problem by properly marking the end of
a multi descriptor transmission.
Fixes: 23f0703c12
("lan743x: Add main source files for new lan743x driver")
Signed-off-by: Bryan Whitehead <Bryan.Whitehead@microchip.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
d25ed413d5
Коммит
90490ef726
|
@ -1400,7 +1400,8 @@ static int lan743x_tx_frame_start(struct lan743x_tx *tx,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lan743x_tx_frame_add_lso(struct lan743x_tx *tx,
|
static void lan743x_tx_frame_add_lso(struct lan743x_tx *tx,
|
||||||
unsigned int frame_length)
|
unsigned int frame_length,
|
||||||
|
int nr_frags)
|
||||||
{
|
{
|
||||||
/* called only from within lan743x_tx_xmit_frame.
|
/* called only from within lan743x_tx_xmit_frame.
|
||||||
* assuming tx->ring_lock has already been acquired.
|
* assuming tx->ring_lock has already been acquired.
|
||||||
|
@ -1410,6 +1411,10 @@ static void lan743x_tx_frame_add_lso(struct lan743x_tx *tx,
|
||||||
|
|
||||||
/* wrap up previous descriptor */
|
/* wrap up previous descriptor */
|
||||||
tx->frame_data0 |= TX_DESC_DATA0_EXT_;
|
tx->frame_data0 |= TX_DESC_DATA0_EXT_;
|
||||||
|
if (nr_frags <= 0) {
|
||||||
|
tx->frame_data0 |= TX_DESC_DATA0_LS_;
|
||||||
|
tx->frame_data0 |= TX_DESC_DATA0_IOC_;
|
||||||
|
}
|
||||||
tx_descriptor = &tx->ring_cpu_ptr[tx->frame_tail];
|
tx_descriptor = &tx->ring_cpu_ptr[tx->frame_tail];
|
||||||
tx_descriptor->data0 = tx->frame_data0;
|
tx_descriptor->data0 = tx->frame_data0;
|
||||||
|
|
||||||
|
@ -1514,8 +1519,11 @@ static void lan743x_tx_frame_end(struct lan743x_tx *tx,
|
||||||
u32 tx_tail_flags = 0;
|
u32 tx_tail_flags = 0;
|
||||||
|
|
||||||
/* wrap up previous descriptor */
|
/* wrap up previous descriptor */
|
||||||
tx->frame_data0 |= TX_DESC_DATA0_LS_;
|
if ((tx->frame_data0 & TX_DESC_DATA0_DTYPE_MASK_) ==
|
||||||
tx->frame_data0 |= TX_DESC_DATA0_IOC_;
|
TX_DESC_DATA0_DTYPE_DATA_) {
|
||||||
|
tx->frame_data0 |= TX_DESC_DATA0_LS_;
|
||||||
|
tx->frame_data0 |= TX_DESC_DATA0_IOC_;
|
||||||
|
}
|
||||||
|
|
||||||
tx_descriptor = &tx->ring_cpu_ptr[tx->frame_tail];
|
tx_descriptor = &tx->ring_cpu_ptr[tx->frame_tail];
|
||||||
buffer_info = &tx->buffer_info[tx->frame_tail];
|
buffer_info = &tx->buffer_info[tx->frame_tail];
|
||||||
|
@ -1600,7 +1608,7 @@ static netdev_tx_t lan743x_tx_xmit_frame(struct lan743x_tx *tx,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gso)
|
if (gso)
|
||||||
lan743x_tx_frame_add_lso(tx, frame_length);
|
lan743x_tx_frame_add_lso(tx, frame_length, nr_frags);
|
||||||
|
|
||||||
if (nr_frags <= 0)
|
if (nr_frags <= 0)
|
||||||
goto finish;
|
goto finish;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче