aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ps3_gelic_net.c
diff options
context:
space:
mode:
authorGeoff Levand <geoff@infradead.org>2011-07-14 19:03:29 -0400
committerDavid S. Miller <davem@davemloft.net>2011-07-14 19:03:29 -0400
commitecae42d37045ec71831d0e0e493e00b0e0732edd (patch)
tree5f02677e563e83f2296ebb8632f7eecb57e15fea /drivers/net/ps3_gelic_net.c
parent6383c0b35b48bfbd0fc8c6fe126a6603c5a9a4b3 (diff)
net/ps3: Fix gelic RX DMA restart
Fix the condition where PS3 network RX hangs when no network TX is occurring by calling gelic_card_enable_rxdmac() during RX_DMA_CHAIN_END event processing. The gelic hardware automatically clears its RX_DMA_EN flag when it detects an RX_DMA_CHAIN_END event. In its processing of RX_DMA_CHAIN_END the gelic driver is required to set RX_DMA_EN (with a call to gelic_card_enable_rxdmac()) to restart RX DMA transfers. The existing gelic driver code does not set RX_DMA_EN directly in its processing of the RX_DMA_CHAIN_END event, but uses a flag variable card->rx_dma_restart_required to schedule the setting of RX_DMA_EN until next inside the interrupt handler. It seems this delayed setting of RX_DMA_EN causes the hang since the next RX interrupt after the RX_DMA_CHAIN_END event where RX_DMA_EN is scheduled to be set will not occur since RX_DMA_EN was not set. In the case were network TX is occuring, RX_DMA_EN is set in the next TX interrupt and RX processing continues. Signed-off-by: Geoff Levand <geoff@infradead.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ps3_gelic_net.c')
-rw-r--r--drivers/net/ps3_gelic_net.c21
1 files changed, 8 insertions, 13 deletions
diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c
index 4acc17bffc42..d82a82d9870c 100644
--- a/drivers/net/ps3_gelic_net.c
+++ b/drivers/net/ps3_gelic_net.c
@@ -993,10 +993,6 @@ static int gelic_card_decode_one_descr(struct gelic_card *card)
993 int dmac_chain_ended; 993 int dmac_chain_ended;
994 994
995 status = gelic_descr_get_status(descr); 995 status = gelic_descr_get_status(descr);
996 /* is this descriptor terminated with next_descr == NULL? */
997 dmac_chain_ended =
998 be32_to_cpu(descr->dmac_cmd_status) &
999 GELIC_DESCR_RX_DMA_CHAIN_END;
1000 996
1001 if (status == GELIC_DESCR_DMA_CARDOWNED) 997 if (status == GELIC_DESCR_DMA_CARDOWNED)
1002 return 0; 998 return 0;
@@ -1059,6 +1055,11 @@ static int gelic_card_decode_one_descr(struct gelic_card *card)
1059 /* ok, we've got a packet in descr */ 1055 /* ok, we've got a packet in descr */
1060 gelic_net_pass_skb_up(descr, card, netdev); 1056 gelic_net_pass_skb_up(descr, card, netdev);
1061refill: 1057refill:
1058
1059 /* is the current descriptor terminated with next_descr == NULL? */
1060 dmac_chain_ended =
1061 be32_to_cpu(descr->dmac_cmd_status) &
1062 GELIC_DESCR_RX_DMA_CHAIN_END;
1062 /* 1063 /*
1063 * So that always DMAC can see the end 1064 * So that always DMAC can see the end
1064 * of the descriptor chain to avoid 1065 * of the descriptor chain to avoid
@@ -1087,10 +1088,9 @@ refill:
1087 * If dmac chain was met, DMAC stopped. 1088 * If dmac chain was met, DMAC stopped.
1088 * thus re-enable it 1089 * thus re-enable it
1089 */ 1090 */
1090 if (dmac_chain_ended) { 1091
1091 card->rx_dma_restart_required = 1; 1092 if (dmac_chain_ended)
1092 dev_dbg(ctodev(card), "reenable rx dma scheduled\n"); 1093 gelic_card_enable_rxdmac(card);
1093 }
1094 1094
1095 return 1; 1095 return 1;
1096} 1096}
@@ -1156,11 +1156,6 @@ static irqreturn_t gelic_card_interrupt(int irq, void *ptr)
1156 1156
1157 status &= card->irq_mask; 1157 status &= card->irq_mask;
1158 1158
1159 if (card->rx_dma_restart_required) {
1160 card->rx_dma_restart_required = 0;
1161 gelic_card_enable_rxdmac(card);
1162 }
1163
1164 if (status & GELIC_CARD_RXINT) { 1159 if (status & GELIC_CARD_RXINT) {
1165 gelic_card_rx_irq_off(card); 1160 gelic_card_rx_irq_off(card);
1166 napi_schedule(&card->napi); 1161 napi_schedule(&card->napi);