Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[pandora-kernel.git] / drivers / net / ps3_gelic_net.c
index b1f251d..d82a82d 100644 (file)
@@ -28,6 +28,7 @@
 
 #undef DEBUG
 
+#include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/slab.h>
@@ -837,9 +838,11 @@ static int gelic_card_kick_txdma(struct gelic_card *card,
                card->tx_dma_progress = 1;
                status = lv1_net_start_tx_dma(bus_id(card), dev_id(card),
                                              descr->bus_addr, 0);
-               if (status)
+               if (status) {
+                       card->tx_dma_progress = 0;
                        dev_info(ctodev(card), "lv1_net_start_txdma failed," \
                                 "status=%d\n", status);
+               }
        }
        return status;
 }
@@ -875,7 +878,7 @@ int gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
        result = gelic_descr_prepare_tx(card, descr, skb);
        if (result) {
                /*
-                * DMA map failed.  As chanses are that failure
+                * DMA map failed.  As chances are that failure
                 * would continue, just release skb and return
                 */
                netdev->stats.tx_dropped++;
@@ -896,12 +899,16 @@ int gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
        if (gelic_card_kick_txdma(card, descr)) {
                /*
                 * kick failed.
-                * release descriptors which were just prepared
+                * release descriptor which was just prepared
                 */
                netdev->stats.tx_dropped++;
+               /* don't trigger BUG_ON() in gelic_descr_release_tx */
+               descr->data_status = cpu_to_be32(GELIC_DESCR_TX_TAIL);
                gelic_descr_release_tx(card, descr);
-               gelic_descr_release_tx(card, descr->next);
-               card->tx_chain.tail = descr->next->next;
+               /* reset head */
+               card->tx_chain.head = descr;
+               /* reset hw termination */
+               descr->prev->next_descr_addr = 0;
                dev_info(ctodev(card), "%s: kick failure\n", __func__);
        }
 
@@ -986,10 +993,6 @@ static int gelic_card_decode_one_descr(struct gelic_card *card)
        int dmac_chain_ended;
 
        status = gelic_descr_get_status(descr);
-       /* is this descriptor terminated with next_descr == NULL? */
-       dmac_chain_ended =
-               be32_to_cpu(descr->dmac_cmd_status) &
-               GELIC_DESCR_RX_DMA_CHAIN_END;
 
        if (status == GELIC_DESCR_DMA_CARDOWNED)
                return 0;
@@ -1009,7 +1012,7 @@ static int gelic_card_decode_one_descr(struct gelic_card *card)
                                netdev = card->netdev[i];
                                break;
                        }
-               };
+               }
                if (GELIC_PORT_MAX <= i) {
                        pr_info("%s: unknown packet vid=%x\n", __func__, vid);
                        goto refill;
@@ -1040,7 +1043,7 @@ static int gelic_card_decode_one_descr(struct gelic_card *card)
                goto refill;
        }
        /*
-        * descriptoers any other than FRAME_END here should
+        * descriptors any other than FRAME_END here should
         * be treated as error.
         */
        if (status != GELIC_DESCR_DMA_FRAME_END) {
@@ -1052,6 +1055,11 @@ static int gelic_card_decode_one_descr(struct gelic_card *card)
        /* ok, we've got a packet in descr */
        gelic_net_pass_skb_up(descr, card, netdev);
 refill:
+
+       /* is the current descriptor terminated with next_descr == NULL? */
+       dmac_chain_ended =
+               be32_to_cpu(descr->dmac_cmd_status) &
+               GELIC_DESCR_RX_DMA_CHAIN_END;
        /*
         * So that always DMAC can see the end
         * of the descriptor chain to avoid
@@ -1080,10 +1088,9 @@ refill:
         * If dmac chain was met, DMAC stopped.
         * thus re-enable it
         */
-       if (dmac_chain_ended) {
-               card->rx_dma_restart_required = 1;
-               dev_dbg(ctodev(card), "reenable rx dma scheduled\n");
-       }
+
+       if (dmac_chain_ended)
+               gelic_card_enable_rxdmac(card);
 
        return 1;
 }
@@ -1149,11 +1156,6 @@ static irqreturn_t gelic_card_interrupt(int irq, void *ptr)
 
        status &= card->irq_mask;
 
-       if (card->rx_dma_restart_required) {
-               card->rx_dma_restart_required = 0;
-               gelic_card_enable_rxdmac(card);
-       }
-
        if (status & GELIC_CARD_RXINT) {
                gelic_card_rx_irq_off(card);
                napi_schedule(&card->napi);
@@ -1199,7 +1201,7 @@ void gelic_net_poll_controller(struct net_device *netdev)
 #endif /* CONFIG_NET_POLL_CONTROLLER */
 
 /**
- * gelic_net_open - called upon ifonfig up
+ * gelic_net_open - called upon ifconfig up
  * @netdev: interface device structure
  *
  * returns 0 on success, <0 on failure