Skip to content

Commit 805e969

Browse files
Toshiharu Okadadavem330
authored andcommitted
pch_gbe: Fixed the issue on which a network freezes
The pch_gbe driver has an issue which a network stops, when receiving traffic is high. In the case, The link down and up are necessary to return a network. This patch fixed this issue. Signed-off-by: Toshiharu Okada <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 5f3a114 commit 805e969

File tree

1 file changed

+27
-29
lines changed

1 file changed

+27
-29
lines changed

drivers/net/pch_gbe/pch_gbe_main.c

Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1199,6 +1199,8 @@ static irqreturn_t pch_gbe_intr(int irq, void *data)
11991199
iowrite32((int_en & ~PCH_GBE_INT_RX_FIFO_ERR),
12001200
&hw->reg->INT_EN);
12011201
pch_gbe_stop_receive(adapter);
1202+
int_st |= ioread32(&hw->reg->INT_ST);
1203+
int_st = int_st & ioread32(&hw->reg->INT_EN);
12021204
}
12031205
if (int_st & PCH_GBE_INT_RX_DMA_ERR)
12041206
adapter->stats.intr_rx_dma_err_count++;
@@ -1218,14 +1220,11 @@ static irqreturn_t pch_gbe_intr(int irq, void *data)
12181220
/* Set Pause packet */
12191221
pch_gbe_mac_set_pause_packet(hw);
12201222
}
1221-
if ((int_en & (PCH_GBE_INT_RX_DMA_CMPLT | PCH_GBE_INT_TX_CMPLT))
1222-
== 0) {
1223-
return IRQ_HANDLED;
1224-
}
12251223
}
12261224

12271225
/* When request status is Receive interruption */
1228-
if ((int_st & (PCH_GBE_INT_RX_DMA_CMPLT | PCH_GBE_INT_TX_CMPLT))) {
1226+
if ((int_st & (PCH_GBE_INT_RX_DMA_CMPLT | PCH_GBE_INT_TX_CMPLT)) ||
1227+
(adapter->rx_stop_flag == true)) {
12291228
if (likely(napi_schedule_prep(&adapter->napi))) {
12301229
/* Enable only Rx Descriptor empty */
12311230
atomic_inc(&adapter->irq_sem);
@@ -1385,7 +1384,7 @@ pch_gbe_clean_tx(struct pch_gbe_adapter *adapter,
13851384
struct sk_buff *skb;
13861385
unsigned int i;
13871386
unsigned int cleaned_count = 0;
1388-
bool cleaned = false;
1387+
bool cleaned = true;
13891388

13901389
pr_debug("next_to_clean : %d\n", tx_ring->next_to_clean);
13911390

@@ -1396,7 +1395,6 @@ pch_gbe_clean_tx(struct pch_gbe_adapter *adapter,
13961395

13971396
while ((tx_desc->gbec_status & DSC_INIT16) == 0x0000) {
13981397
pr_debug("gbec_status:0x%04x\n", tx_desc->gbec_status);
1399-
cleaned = true;
14001398
buffer_info = &tx_ring->buffer_info[i];
14011399
skb = buffer_info->skb;
14021400

@@ -1439,8 +1437,10 @@ pch_gbe_clean_tx(struct pch_gbe_adapter *adapter,
14391437
tx_desc = PCH_GBE_TX_DESC(*tx_ring, i);
14401438

14411439
/* weight of a sort for tx, to avoid endless transmit cleanup */
1442-
if (cleaned_count++ == PCH_GBE_TX_WEIGHT)
1440+
if (cleaned_count++ == PCH_GBE_TX_WEIGHT) {
1441+
cleaned = false;
14431442
break;
1443+
}
14441444
}
14451445
pr_debug("called pch_gbe_unmap_and_free_tx_resource() %d count\n",
14461446
cleaned_count);
@@ -2168,41 +2168,39 @@ static int pch_gbe_napi_poll(struct napi_struct *napi, int budget)
21682168
{
21692169
struct pch_gbe_adapter *adapter =
21702170
container_of(napi, struct pch_gbe_adapter, napi);
2171-
struct net_device *netdev = adapter->netdev;
21722171
int work_done = 0;
21732172
bool poll_end_flag = false;
21742173
bool cleaned = false;
21752174
u32 int_en;
21762175

21772176
pr_debug("budget : %d\n", budget);
21782177

2179-
/* Keep link state information with original netdev */
2180-
if (!netif_carrier_ok(netdev)) {
2178+
pch_gbe_clean_rx(adapter, adapter->rx_ring, &work_done, budget);
2179+
cleaned = pch_gbe_clean_tx(adapter, adapter->tx_ring);
2180+
2181+
if (!cleaned)
2182+
work_done = budget;
2183+
/* If no Tx and not enough Rx work done,
2184+
* exit the polling mode
2185+
*/
2186+
if (work_done < budget)
21812187
poll_end_flag = true;
2182-
} else {
2183-
pch_gbe_clean_rx(adapter, adapter->rx_ring, &work_done, budget);
2188+
2189+
if (poll_end_flag) {
2190+
napi_complete(napi);
2191+
if (adapter->rx_stop_flag) {
2192+
adapter->rx_stop_flag = false;
2193+
pch_gbe_start_receive(&adapter->hw);
2194+
}
2195+
pch_gbe_irq_enable(adapter);
2196+
} else
21842197
if (adapter->rx_stop_flag) {
21852198
adapter->rx_stop_flag = false;
21862199
pch_gbe_start_receive(&adapter->hw);
21872200
int_en = ioread32(&adapter->hw.reg->INT_EN);
21882201
iowrite32((int_en | PCH_GBE_INT_RX_FIFO_ERR),
2189-
&adapter->hw.reg->INT_EN);
2202+
&adapter->hw.reg->INT_EN);
21902203
}
2191-
cleaned = pch_gbe_clean_tx(adapter, adapter->tx_ring);
2192-
2193-
if (cleaned)
2194-
work_done = budget;
2195-
/* If no Tx and not enough Rx work done,
2196-
* exit the polling mode
2197-
*/
2198-
if (work_done < budget)
2199-
poll_end_flag = true;
2200-
}
2201-
2202-
if (poll_end_flag) {
2203-
napi_complete(napi);
2204-
pch_gbe_irq_enable(adapter);
2205-
}
22062204

22072205
pr_debug("poll_end_flag : %d work_done : %d budget : %d\n",
22082206
poll_end_flag, work_done, budget);

0 commit comments

Comments
 (0)