* [PATCH v4 1/9] pasemi_mac: Move the IRQ mapping from the PCI layer to the driver
[not found] <20070508053500.358169000@localhost.localdomain>
@ 2007-05-08 5:47 ` Olof Johansson
2007-05-08 5:48 ` Jeff Garzik
2007-05-08 5:47 ` [PATCH v4 2/9] pasemi_mac: Abstract and fix up interrupt restart routines Olof Johansson
` (7 subsequent siblings)
8 siblings, 1 reply; 10+ messages in thread
From: Olof Johansson @ 2007-05-08 5:47 UTC (permalink / raw)
To: jgarzik; +Cc: netdev
[-- Attachment #1: n-2 --]
[-- Type: text/plain, Size: 4116 bytes --]
Fixes for ethernet IRQ mapping, to be done in the driver instead of in
the platform setup code.
Signed-off-by: Olof Johansson <olof@lixom.net>
Index: netdev-2.6/arch/powerpc/platforms/pasemi/pci.c
===================================================================
--- netdev-2.6.orig/arch/powerpc/platforms/pasemi/pci.c
+++ netdev-2.6/arch/powerpc/platforms/pasemi/pci.c
@@ -173,19 +173,6 @@ static void __init pas_fixup_phb_resourc
}
-void __devinit pas_pci_irq_fixup(struct pci_dev *dev)
-{
- /* DMA is special, 84 interrupts (128 -> 211), all but 128
- * need to be mapped by hand here.
- */
- if (dev->vendor == 0x1959 && dev->device == 0xa007) {
- int i;
- for (i = 129; i < 212; i++)
- irq_create_mapping(NULL, i);
- }
-}
-
-
void __init pas_pci_init(void)
{
struct device_node *np, *root;
Index: netdev-2.6/arch/powerpc/platforms/pasemi/setup.c
===================================================================
--- netdev-2.6.orig/arch/powerpc/platforms/pasemi/setup.c
+++ netdev-2.6/arch/powerpc/platforms/pasemi/setup.c
@@ -248,5 +248,4 @@ define_machine(pas) {
.calibrate_decr = generic_calibrate_decr,
.progress = pas_progress,
.machine_check_exception = pas_machine_check_handler,
- .pci_irq_fixup = pas_pci_irq_fixup,
};
Index: netdev-2.6/drivers/net/pasemi_mac.c
===================================================================
--- netdev-2.6.orig/drivers/net/pasemi_mac.c
+++ netdev-2.6/drivers/net/pasemi_mac.c
@@ -33,6 +33,8 @@
#include <linux/tcp.h>
#include <net/checksum.h>
+#include <asm/irq.h>
+
#include "pasemi_mac.h"
@@ -531,6 +533,7 @@ static irqreturn_t pasemi_mac_tx_intr(in
static int pasemi_mac_open(struct net_device *dev)
{
struct pasemi_mac *mac = netdev_priv(dev);
+ int base_irq;
unsigned int flags;
int ret;
@@ -594,28 +597,37 @@ static int pasemi_mac_open(struct net_de
netif_start_queue(dev);
netif_poll_enable(dev);
- ret = request_irq(mac->dma_pdev->irq + mac->dma_txch,
- &pasemi_mac_tx_intr, IRQF_DISABLED,
+ /* Interrupts are a bit different for our DMA controller: While
+ * it's got one a regular PCI device header, the interrupt there
+ * is really the base of the range it's using. Each tx and rx
+ * channel has it's own interrupt source.
+ */
+
+ base_irq = virq_to_hw(mac->dma_pdev->irq);
+
+ mac->tx_irq = irq_create_mapping(NULL, base_irq + mac->dma_txch);
+ mac->rx_irq = irq_create_mapping(NULL, base_irq + 20 + mac->dma_txch);
+
+ ret = request_irq(mac->tx_irq, &pasemi_mac_tx_intr, IRQF_DISABLED,
mac->tx->irq_name, dev);
if (ret) {
dev_err(&mac->pdev->dev, "request_irq of irq %d failed: %d\n",
- mac->dma_pdev->irq + mac->dma_txch, ret);
+ base_irq + mac->dma_txch, ret);
goto out_tx_int;
}
- ret = request_irq(mac->dma_pdev->irq + 20 + mac->dma_rxch,
- &pasemi_mac_rx_intr, IRQF_DISABLED,
+ ret = request_irq(mac->rx_irq, &pasemi_mac_rx_intr, IRQF_DISABLED,
mac->rx->irq_name, dev);
if (ret) {
dev_err(&mac->pdev->dev, "request_irq of irq %d failed: %d\n",
- mac->dma_pdev->irq + 20 + mac->dma_rxch, ret);
+ base_irq + 20 + mac->dma_rxch, ret);
goto out_rx_int;
}
return 0;
out_rx_int:
- free_irq(mac->dma_pdev->irq + mac->dma_txch, dev);
+ free_irq(mac->tx_irq, dev);
out_tx_int:
netif_poll_disable(dev);
netif_stop_queue(dev);
@@ -699,8 +711,8 @@ static int pasemi_mac_close(struct net_d
pci_write_config_dword(mac->dma_pdev,
PAS_DMA_RXINT_RCMDSTA(mac->dma_if), 0);
- free_irq(mac->dma_pdev->irq + mac->dma_txch, dev);
- free_irq(mac->dma_pdev->irq + 20 + mac->dma_rxch, dev);
+ free_irq(mac->tx_irq, dev);
+ free_irq(mac->rx_irq, dev);
/* Free resources */
pasemi_mac_free_rx_resources(dev);
Index: netdev-2.6/drivers/net/pasemi_mac.h
===================================================================
--- netdev-2.6.orig/drivers/net/pasemi_mac.h
+++ netdev-2.6/drivers/net/pasemi_mac.h
@@ -73,6 +73,8 @@ struct pasemi_mac {
struct pasemi_mac_txring *tx;
struct pasemi_mac_rxring *rx;
+ unsigned long tx_irq;
+ unsigned long rx_irq;
};
/* Software status descriptor (desc_info) */
--
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v4 2/9] pasemi_mac: Abstract and fix up interrupt restart routines
[not found] <20070508053500.358169000@localhost.localdomain>
2007-05-08 5:47 ` [PATCH v4 1/9] pasemi_mac: Move the IRQ mapping from the PCI layer to the driver Olof Johansson
@ 2007-05-08 5:47 ` Olof Johansson
2007-05-08 5:47 ` [PATCH v4 3/9] pasemi_mac: Timer and interrupt fixes Olof Johansson
` (6 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Olof Johansson @ 2007-05-08 5:47 UTC (permalink / raw)
To: jgarzik; +Cc: netdev
[-- Attachment #1: n-3 --]
[-- Type: text/plain, Size: 2374 bytes --]
Abstract out (and fix up) the interrupt restart routines, making
sure we start out in a consistent state.
Signed-off-by: Olof Johansson <olof@lixom.net>
Index: netdev-2.6/drivers/net/pasemi_mac.c
===================================================================
--- netdev-2.6.orig/drivers/net/pasemi_mac.c
+++ netdev-2.6/drivers/net/pasemi_mac.c
@@ -362,6 +362,42 @@ static void pasemi_mac_replenish_rx_ring
mac->rx->next_to_fill += count;
}
+static void pasemi_mac_restart_rx_intr(struct pasemi_mac *mac)
+{
+ unsigned int reg, stat;
+ /* Re-enable packet count interrupts: finally
+ * ack the packet count interrupt we got in rx_intr.
+ */
+
+ pci_read_config_dword(mac->iob_pdev,
+ PAS_IOB_DMA_RXCH_STAT(mac->dma_rxch),
+ &stat);
+
+ reg = PAS_IOB_DMA_RXCH_RESET_PCNT(stat & PAS_IOB_DMA_RXCH_STAT_CNTDEL_M)
+ | PAS_IOB_DMA_RXCH_RESET_PINTC;
+
+ pci_write_config_dword(mac->iob_pdev,
+ PAS_IOB_DMA_RXCH_RESET(mac->dma_rxch),
+ reg);
+}
+
+static void pasemi_mac_restart_tx_intr(struct pasemi_mac *mac)
+{
+ unsigned int reg, stat;
+
+ /* Re-enable packet count interrupts */
+ pci_read_config_dword(mac->iob_pdev,
+ PAS_IOB_DMA_TXCH_STAT(mac->dma_txch), &stat);
+
+ reg = PAS_IOB_DMA_TXCH_RESET_PCNT(stat & PAS_IOB_DMA_TXCH_STAT_CNTDEL_M)
+ | PAS_IOB_DMA_TXCH_RESET_PINTC;
+
+ pci_write_config_dword(mac->iob_pdev,
+ PAS_IOB_DMA_TXCH_RESET(mac->dma_txch), reg);
+}
+
+
+
static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
{
unsigned int i;
@@ -559,6 +595,10 @@ static int pasemi_mac_open(struct net_de
pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_RXCH_CFG(mac->dma_rxch),
PAS_IOB_DMA_RXCH_CFG_CNTTH(30));
+ /* Clear out any residual packet count state from firmware */
+ pasemi_mac_restart_rx_intr(mac);
+ pasemi_mac_restart_tx_intr(mac);
+
pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_COM_TIMEOUTCFG,
PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(1000000));
@@ -835,9 +875,7 @@ static int pasemi_mac_poll(struct net_de
/* all done, no more packets present */
netif_rx_complete(dev);
- /* re-enable receive interrupts */
- pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_COM_TIMEOUTCFG,
- PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(1000000));
+ pasemi_mac_restart_rx_intr(mac);
return 0;
} else {
/* used up our quantum, so reschedule */
--
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v4 3/9] pasemi_mac: Timer and interrupt fixes
[not found] <20070508053500.358169000@localhost.localdomain>
2007-05-08 5:47 ` [PATCH v4 1/9] pasemi_mac: Move the IRQ mapping from the PCI layer to the driver Olof Johansson
2007-05-08 5:47 ` [PATCH v4 2/9] pasemi_mac: Abstract and fix up interrupt restart routines Olof Johansson
@ 2007-05-08 5:47 ` Olof Johansson
2007-05-08 5:47 ` [PATCH v4 4/9] pasemi_mac: Add SKB reuse / copy-break Olof Johansson
` (5 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Olof Johansson @ 2007-05-08 5:47 UTC (permalink / raw)
To: jgarzik; +Cc: netdev
[-- Attachment #1: n-4 --]
[-- Type: text/plain, Size: 3777 bytes --]
Timer and interrupt fixes:
* Be pickier with what kind of interrupts are acked to avoid the device to
get out of sync with the driver state
* Set RX count threshhold to 1 (for NAPI interrupted mode), TX count
threshold to 32.
* Set timer thresholds to current max (~16ms).
Signed-off-by: Olof Johansson <olof@lixom.net>
Index: netdev-2.6/drivers/net/pasemi_mac.c
===================================================================
--- netdev-2.6.orig/drivers/net/pasemi_mac.c
+++ netdev-2.6/drivers/net/pasemi_mac.c
@@ -526,18 +526,28 @@ static irqreturn_t pasemi_mac_rx_intr(in
struct pasemi_mac *mac = netdev_priv(dev);
unsigned int reg;
- if (!(*mac->rx_status & PAS_STATUS_INT))
+ if (!(*mac->rx_status & PAS_STATUS_CAUSE_M))
return IRQ_NONE;
- netif_rx_schedule(dev);
- pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_COM_TIMEOUTCFG,
- PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(0));
+ if (*mac->rx_status & PAS_STATUS_ERROR)
+ printk("rx_status reported error\n");
+
+ /* Don't reset packet count so it won't fire again but clear
+ * all others.
+ */
+
+ pci_read_config_dword(mac->dma_pdev, PAS_DMA_RXINT_RCMDSTA(mac->dma_if), ®);
- reg = PAS_IOB_DMA_RXCH_RESET_PINTC | PAS_IOB_DMA_RXCH_RESET_SINTC |
- PAS_IOB_DMA_RXCH_RESET_DINTC;
+ reg = 0;
+ if (*mac->rx_status & PAS_STATUS_SOFT)
+ reg |= PAS_IOB_DMA_RXCH_RESET_SINTC;
+ if (*mac->rx_status & PAS_STATUS_ERROR)
+ reg |= PAS_IOB_DMA_RXCH_RESET_DINTC;
if (*mac->rx_status & PAS_STATUS_TIMER)
reg |= PAS_IOB_DMA_RXCH_RESET_TINTC;
+ netif_rx_schedule(dev);
+
pci_write_config_dword(mac->iob_pdev,
PAS_IOB_DMA_RXCH_RESET(mac->dma_rxch), reg);
@@ -551,14 +561,17 @@ static irqreturn_t pasemi_mac_tx_intr(in
struct pasemi_mac *mac = netdev_priv(dev);
unsigned int reg;
- if (!(*mac->tx_status & PAS_STATUS_INT))
+ if (!(*mac->tx_status & PAS_STATUS_CAUSE_M))
return IRQ_NONE;
pasemi_mac_clean_tx(mac);
- reg = PAS_IOB_DMA_TXCH_RESET_PINTC | PAS_IOB_DMA_TXCH_RESET_SINTC;
- if (*mac->tx_status & PAS_STATUS_TIMER)
- reg |= PAS_IOB_DMA_TXCH_RESET_TINTC;
+ reg = PAS_IOB_DMA_TXCH_RESET_PINTC;
+
+ if (*mac->tx_status & PAS_STATUS_SOFT)
+ reg |= PAS_IOB_DMA_TXCH_RESET_SINTC;
+ if (*mac->tx_status & PAS_STATUS_ERROR)
+ reg |= PAS_IOB_DMA_TXCH_RESET_DINTC;
pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_TXCH_RESET(mac->dma_txch),
reg);
@@ -593,14 +606,18 @@ static int pasemi_mac_open(struct net_de
flags |= PAS_MAC_CFG_PCFG_TSR_1G | PAS_MAC_CFG_PCFG_SPD_1G;
pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_RXCH_CFG(mac->dma_rxch),
- PAS_IOB_DMA_RXCH_CFG_CNTTH(30));
+ PAS_IOB_DMA_RXCH_CFG_CNTTH(1));
+
+ pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_TXCH_CFG(mac->dma_txch),
+ PAS_IOB_DMA_TXCH_CFG_CNTTH(32));
/* Clear out any residual packet count state from firmware */
pasemi_mac_restart_rx_intr(mac);
pasemi_mac_restart_tx_intr(mac);
+ /* 0xffffff is max value, about 16ms */
pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_COM_TIMEOUTCFG,
- PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(1000000));
+ PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(0xffffff));
pci_write_config_dword(mac->pdev, PAS_MAC_CFG_PCFG, flags);
Index: netdev-2.6/drivers/net/pasemi_mac.h
===================================================================
--- netdev-2.6.orig/drivers/net/pasemi_mac.h
+++ netdev-2.6/drivers/net/pasemi_mac.h
@@ -299,6 +299,7 @@ enum {
#define PAS_STATUS_DCNT_S 16
#define PAS_STATUS_BPCNT_M 0x0000ffff00000000ull
#define PAS_STATUS_BPCNT_S 32
+#define PAS_STATUS_CAUSE_M 0xf000000000000000ull
#define PAS_STATUS_TIMER 0x1000000000000000ull
#define PAS_STATUS_ERROR 0x2000000000000000ull
#define PAS_STATUS_SOFT 0x4000000000000000ull
--
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v4 4/9] pasemi_mac: Add SKB reuse / copy-break
[not found] <20070508053500.358169000@localhost.localdomain>
` (2 preceding siblings ...)
2007-05-08 5:47 ` [PATCH v4 3/9] pasemi_mac: Timer and interrupt fixes Olof Johansson
@ 2007-05-08 5:47 ` Olof Johansson
2007-05-08 5:47 ` [PATCH v4 5/9] pasemi_mac: Minor cleanup / define fixes Olof Johansson
` (4 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Olof Johansson @ 2007-05-08 5:47 UTC (permalink / raw)
To: jgarzik; +Cc: netdev
[-- Attachment #1: n-5 --]
[-- Type: text/plain, Size: 1876 bytes --]
Add a copy-break and recycle the SKB in the driver for small packets.
Signed-off-by: Olof Johansson <olof@lixom.net>
Index: netdev-2.6/drivers/net/pasemi_mac.c
===================================================================
--- netdev-2.6.orig/drivers/net/pasemi_mac.c
+++ netdev-2.6/drivers/net/pasemi_mac.c
@@ -279,8 +279,8 @@ static void pasemi_mac_free_rx_resources
for (i = 0; i < RX_RING_SIZE; i++) {
info = &RX_DESC_INFO(mac, i);
dp = &RX_DESC(mac, i);
- if (info->dma) {
- if (info->skb) {
+ if (info->skb) {
+ if (info->dma) {
pci_unmap_single(mac->dma_pdev,
info->dma,
info->skb->len,
@@ -329,12 +329,14 @@ static void pasemi_mac_replenish_rx_ring
struct sk_buff *skb;
dma_addr_t dma;
- skb = dev_alloc_skb(BUF_SIZE);
+ /* skb might still be in there for recycle on short receives */
+ if (info->skb)
+ skb = info->skb;
+ else
+ skb = dev_alloc_skb(BUF_SIZE);
- if (!skb) {
- count = i - start;
+ if (unlikely(!skb))
break;
- }
dma = pci_map_single(mac->dma_pdev, skb->data, skb->len,
PCI_DMA_FROMDEVICE);
@@ -442,13 +444,28 @@ static int pasemi_mac_clean_rx(struct pa
BUG_ON(!info);
BUG_ON(info->dma != dma);
+ skb = info->skb;
pci_unmap_single(mac->dma_pdev, info->dma, info->skb->len,
PCI_DMA_FROMDEVICE);
+ info->dma = 0;
- skb = info->skb;
len = (dp->macrx & XCT_MACRX_LLEN_M) >> XCT_MACRX_LLEN_S;
+ if (len < 256) {
+ struct sk_buff *new_skb =
+ netdev_alloc_skb(mac->netdev, len + NET_IP_ALIGN);
+ if (new_skb) {
+ skb_reserve(new_skb, NET_IP_ALIGN);
+ memcpy(new_skb->data - NET_IP_ALIGN,
+ skb->data - NET_IP_ALIGN,
+ len + NET_IP_ALIGN);
+ /* save the skb in buffer_info as good */
+ skb = new_skb;
+ }
+ /* else just continue with the old one */
+ } else
+ info->skb = NULL;
skb_put(skb, len);
--
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v4 5/9] pasemi_mac: Minor cleanup / define fixes
[not found] <20070508053500.358169000@localhost.localdomain>
` (3 preceding siblings ...)
2007-05-08 5:47 ` [PATCH v4 4/9] pasemi_mac: Add SKB reuse / copy-break Olof Johansson
@ 2007-05-08 5:47 ` Olof Johansson
2007-05-08 5:47 ` [PATCH v4 6/9] pasemi_mac: Logic cleanup / rx performance improvements Olof Johansson
` (3 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Olof Johansson @ 2007-05-08 5:47 UTC (permalink / raw)
To: jgarzik; +Cc: netdev
[-- Attachment #1: n-6 --]
[-- Type: text/plain, Size: 1971 bytes --]
* Remove some unused defines
* Fix a couple of wrong chip register defines, and add a few more fields
that might be used in the near future.
Signed-off-by: Olof Johansson <olof@lixom.net>
Index: netdev-2.6/drivers/net/pasemi_mac.c
===================================================================
--- netdev-2.6.orig/drivers/net/pasemi_mac.c
+++ netdev-2.6/drivers/net/pasemi_mac.c
@@ -61,12 +61,6 @@
#define BUF_SIZE 1646 /* 1500 MTU + ETH_HLEN + VLAN_HLEN + 2 64B cachelines */
-/* XXXOJN these should come out of the device tree some day */
-#define PAS_DMA_CAP_BASE 0xe00d0040
-#define PAS_DMA_CAP_SIZE 0x100
-#define PAS_DMA_COM_BASE 0xe00d0100
-#define PAS_DMA_COM_SIZE 0x100
-
static struct pasdma_status *dma_status;
static int pasemi_get_mac_addr(struct pasemi_mac *mac)
Index: netdev-2.6/drivers/net/pasemi_mac.h
===================================================================
--- netdev-2.6.orig/drivers/net/pasemi_mac.h
+++ netdev-2.6/drivers/net/pasemi_mac.h
@@ -195,11 +195,15 @@ enum {
#define PAS_DMA_RXINT_RCMDSTA(i) (0x200+(i)*_PAS_DMA_RXINT_STRIDE)
#define PAS_DMA_RXINT_RCMDSTA_EN 0x00000001
#define PAS_DMA_RXINT_RCMDSTA_ST 0x00000002
-#define PAS_DMA_RXINT_RCMDSTA_OO 0x00000100
-#define PAS_DMA_RXINT_RCMDSTA_BP 0x00000200
-#define PAS_DMA_RXINT_RCMDSTA_DR 0x00000400
+#define PAS_DMA_RXINT_RCMDSTA_MBT 0x00000008
+#define PAS_DMA_RXINT_RCMDSTA_MDR 0x00000010
+#define PAS_DMA_RXINT_RCMDSTA_MOO 0x00000020
+#define PAS_DMA_RXINT_RCMDSTA_MBP 0x00000040
#define PAS_DMA_RXINT_RCMDSTA_BT 0x00000800
-#define PAS_DMA_RXINT_RCMDSTA_TB 0x00001000
+#define PAS_DMA_RXINT_RCMDSTA_DR 0x00001000
+#define PAS_DMA_RXINT_RCMDSTA_OO 0x00002000
+#define PAS_DMA_RXINT_RCMDSTA_BP 0x00004000
+#define PAS_DMA_RXINT_RCMDSTA_TB 0x00008000
#define PAS_DMA_RXINT_RCMDSTA_ACT 0x00010000
#define PAS_DMA_RXINT_RCMDSTA_DROPS_M 0xfffe0000
#define PAS_DMA_RXINT_RCMDSTA_DROPS_S 17
--
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v4 6/9] pasemi_mac: Logic cleanup / rx performance improvements
[not found] <20070508053500.358169000@localhost.localdomain>
` (4 preceding siblings ...)
2007-05-08 5:47 ` [PATCH v4 5/9] pasemi_mac: Minor cleanup / define fixes Olof Johansson
@ 2007-05-08 5:47 ` Olof Johansson
2007-05-08 5:47 ` [PATCH v4 7/9] pasemi_mac: Add msglevel support and "debug" module param Olof Johansson
` (2 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Olof Johansson @ 2007-05-08 5:47 UTC (permalink / raw)
To: jgarzik; +Cc: netdev
[-- Attachment #1: n-7 --]
[-- Type: text/plain, Size: 4895 bytes --]
Logic cleanup and some performance enhancements to the RX path.
Signed-off-by: Olof Johansson <olof@lixom.net>
Index: netdev-2.6/drivers/net/pasemi_mac.c
===================================================================
--- netdev-2.6.orig/drivers/net/pasemi_mac.c
+++ netdev-2.6/drivers/net/pasemi_mac.c
@@ -305,19 +305,20 @@ static void pasemi_mac_replenish_rx_ring
struct pasemi_mac *mac = netdev_priv(dev);
unsigned int i;
int start = mac->rx->next_to_fill;
- unsigned int count;
+ unsigned int limit, count;
- count = (mac->rx->next_to_clean + RX_RING_SIZE -
+ limit = (mac->rx->next_to_clean + RX_RING_SIZE -
mac->rx->next_to_fill) & (RX_RING_SIZE - 1);
/* Check to see if we're doing first-time setup */
if (unlikely(mac->rx->next_to_clean == 0 && mac->rx->next_to_fill == 0))
- count = RX_RING_SIZE;
+ limit = RX_RING_SIZE;
- if (count <= 0)
+ if (limit <= 0)
return;
- for (i = start; i < start + count; i++) {
+ i = start;
+ for (count = limit; count; count--) {
struct pasemi_mac_buffer *info = &RX_DESC_INFO(mac, i);
u64 *buff = &RX_BUFF(mac, i);
struct sk_buff *skb;
@@ -335,27 +336,27 @@ static void pasemi_mac_replenish_rx_ring
dma = pci_map_single(mac->dma_pdev, skb->data, skb->len,
PCI_DMA_FROMDEVICE);
- if (dma_mapping_error(dma)) {
+ if (unlikely(dma_mapping_error(dma))) {
dev_kfree_skb_irq(info->skb);
- count = i - start;
break;
}
info->skb = skb;
info->dma = dma;
*buff = XCT_RXB_LEN(BUF_SIZE) | XCT_RXB_ADDR(dma);
+ i++;
}
wmb();
pci_write_config_dword(mac->dma_pdev,
PAS_DMA_RXCHAN_INCR(mac->dma_rxch),
- count);
+ limit - count);
pci_write_config_dword(mac->dma_pdev,
PAS_DMA_RXINT_INCR(mac->dma_if),
- count);
+ limit - count);
- mac->rx->next_to_fill += count;
+ mac->rx->next_to_fill += limit - count;
}
static void pasemi_mac_restart_rx_intr(struct pasemi_mac *mac)
@@ -393,32 +394,31 @@ static void pasemi_mac_restart_tx_intr(s
}
-
static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
{
- unsigned int i;
- int start, count;
+ unsigned int n;
+ int count;
+ struct pas_dma_xct_descr *dp;
+ struct pasemi_mac_buffer *info;
+ struct sk_buff *skb;
+ unsigned int i, len;
+ u64 macrx;
+ dma_addr_t dma;
spin_lock(&mac->rx->lock);
- start = mac->rx->next_to_clean;
- count = 0;
+ n = mac->rx->next_to_clean;
- for (i = start; i < (start + RX_RING_SIZE) && count < limit; i++) {
- struct pas_dma_xct_descr *dp;
- struct pasemi_mac_buffer *info;
- struct sk_buff *skb;
- unsigned int j, len;
- dma_addr_t dma;
+ for (count = limit; count; count--) {
rmb();
- dp = &RX_DESC(mac, i);
+ dp = &RX_DESC(mac, n);
+ macrx = dp->macrx;
- if (!(dp->macrx & XCT_MACRX_O))
+ if (!(macrx & XCT_MACRX_O))
break;
- count++;
info = NULL;
@@ -430,22 +430,20 @@ static int pasemi_mac_clean_rx(struct pa
*/
dma = (dp->ptr & XCT_PTR_ADDR_M);
- for (j = start; j < (start + RX_RING_SIZE); j++) {
- info = &RX_DESC_INFO(mac, j);
+ for (i = n; i < (n + RX_RING_SIZE); i++) {
+ info = &RX_DESC_INFO(mac, i);
if (info->dma == dma)
break;
}
- BUG_ON(!info);
- BUG_ON(info->dma != dma);
skb = info->skb;
+ info->dma = 0;
- pci_unmap_single(mac->dma_pdev, info->dma, info->skb->len,
+ pci_unmap_single(mac->dma_pdev, dma, skb->len,
PCI_DMA_FROMDEVICE);
- info->dma = 0;
+ len = (macrx & XCT_MACRX_LLEN_M) >> XCT_MACRX_LLEN_S;
- len = (dp->macrx & XCT_MACRX_LLEN_M) >> XCT_MACRX_LLEN_S;
if (len < 256) {
struct sk_buff *new_skb =
netdev_alloc_skb(mac->netdev, len + NET_IP_ALIGN);
@@ -465,9 +463,9 @@ static int pasemi_mac_clean_rx(struct pa
skb->protocol = eth_type_trans(skb, mac->netdev);
- if ((dp->macrx & XCT_MACRX_HTY_M) == XCT_MACRX_HTY_IPV4_OK) {
+ if ((macrx & XCT_MACRX_HTY_M) == XCT_MACRX_HTY_IPV4_OK) {
skb->ip_summed = CHECKSUM_COMPLETE;
- skb->csum = (dp->macrx & XCT_MACRX_CSUM_M) >>
+ skb->csum = (macrx & XCT_MACRX_CSUM_M) >>
XCT_MACRX_CSUM_S;
} else
skb->ip_summed = CHECKSUM_NONE;
@@ -477,13 +475,13 @@ static int pasemi_mac_clean_rx(struct pa
netif_receive_skb(skb);
- info->dma = 0;
- info->skb = NULL;
dp->ptr = 0;
dp->macrx = 0;
+
+ n++;
}
- mac->rx->next_to_clean += count;
+ mac->rx->next_to_clean += limit - count;
pasemi_mac_replenish_rx_ring(mac->netdev);
spin_unlock(&mac->rx->lock);
@@ -899,6 +897,9 @@ static int pasemi_mac_poll(struct net_de
pkts = pasemi_mac_clean_rx(mac, limit);
+ dev->quota -= pkts;
+ *budget -= pkts;
+
if (pkts < limit) {
/* all done, no more packets present */
netif_rx_complete(dev);
@@ -907,8 +908,6 @@ static int pasemi_mac_poll(struct net_de
return 0;
} else {
/* used up our quantum, so reschedule */
- dev->quota -= pkts;
- *budget -= pkts;
return 1;
}
}
--
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v4 7/9] pasemi_mac: Add msglevel support and "debug" module param
[not found] <20070508053500.358169000@localhost.localdomain>
` (5 preceding siblings ...)
2007-05-08 5:47 ` [PATCH v4 6/9] pasemi_mac: Logic cleanup / rx performance improvements Olof Johansson
@ 2007-05-08 5:47 ` Olof Johansson
2007-05-08 5:47 ` [PATCH v4 8/9] pasemi_mac: PHY support Olof Johansson
2007-05-08 5:48 ` [PATCH v4 9/9] pasemi_mac: Use local-mac-address instead of mac-address if available Olof Johansson
8 siblings, 0 replies; 10+ messages in thread
From: Olof Johansson @ 2007-05-08 5:47 UTC (permalink / raw)
To: jgarzik; +Cc: netdev
[-- Attachment #1: n-8 --]
[-- Type: text/plain, Size: 2614 bytes --]
Add msglevel support for pasemi_mac. Move the MODULE_* defines to the
top to go together with the variable (similar to tg3).
Signed-off-by: Olof Johansson <olof@lixom.net>
Index: netdev-2.6/drivers/net/pasemi_mac.c
===================================================================
--- netdev-2.6.orig/drivers/net/pasemi_mac.c
+++ netdev-2.6/drivers/net/pasemi_mac.c
@@ -53,6 +53,16 @@
#define RX_RING_SIZE 512
#define TX_RING_SIZE 512
+#define DEFAULT_MSG_ENABLE \
+ (NETIF_MSG_DRV | \
+ NETIF_MSG_PROBE | \
+ NETIF_MSG_LINK | \
+ NETIF_MSG_TIMER | \
+ NETIF_MSG_IFDOWN | \
+ NETIF_MSG_IFUP | \
+ NETIF_MSG_RX_ERR | \
+ NETIF_MSG_TX_ERR)
+
#define TX_DESC(mac, num) ((mac)->tx->desc[(num) & (TX_RING_SIZE-1)])
#define TX_DESC_INFO(mac, num) ((mac)->tx->desc_info[(num) & (TX_RING_SIZE-1)])
#define RX_DESC(mac, num) ((mac)->rx->desc[(num) & (RX_RING_SIZE-1)])
@@ -61,6 +71,14 @@
#define BUF_SIZE 1646 /* 1500 MTU + ETH_HLEN + VLAN_HLEN + 2 64B cachelines */
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR ("Olof Johansson <olof@lixom.net>");
+MODULE_DESCRIPTION("PA Semi PWRficient Ethernet driver");
+
+static int debug = -1; /* -1 == use DEFAULT_MSG_ENABLE as value */
+module_param(debug, int, 0);
+MODULE_PARM_DESC(debug, "PA Semi MAC bitmapped debugging message enable value");
+
static struct pasdma_status *dma_status;
static int pasemi_get_mac_addr(struct pasemi_mac *mac)
@@ -873,6 +891,7 @@ static struct net_device_stats *pasemi_m
return &mac->stats;
}
+
static void pasemi_mac_set_rx_mode(struct net_device *dev)
{
struct pasemi_mac *mac = netdev_priv(dev);
@@ -1007,6 +1026,8 @@ pasemi_mac_probe(struct pci_dev *pdev, c
mac->rx_status = &dma_status->rx_sta[mac->dma_rxch];
mac->tx_status = &dma_status->tx_sta[mac->dma_txch];
+ mac->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE);
+
err = register_netdev(dev);
if (err) {
@@ -1081,9 +1102,5 @@ int pasemi_mac_init_module(void)
return pci_register_driver(&pasemi_mac_driver);
}
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR ("Olof Johansson <olof@lixom.net>");
-MODULE_DESCRIPTION("PA Semi PWRficient Ethernet driver");
-
module_init(pasemi_mac_init_module);
module_exit(pasemi_mac_cleanup_module);
Index: netdev-2.6/drivers/net/pasemi_mac.h
===================================================================
--- netdev-2.6.orig/drivers/net/pasemi_mac.h
+++ netdev-2.6/drivers/net/pasemi_mac.h
@@ -75,6 +75,8 @@ struct pasemi_mac {
struct pasemi_mac_rxring *rx;
unsigned long tx_irq;
unsigned long rx_irq;
+
+ unsigned int msg_enable;
};
/* Software status descriptor (desc_info) */
--
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v4 8/9] pasemi_mac: PHY support
[not found] <20070508053500.358169000@localhost.localdomain>
` (6 preceding siblings ...)
2007-05-08 5:47 ` [PATCH v4 7/9] pasemi_mac: Add msglevel support and "debug" module param Olof Johansson
@ 2007-05-08 5:47 ` Olof Johansson
2007-05-08 5:48 ` [PATCH v4 9/9] pasemi_mac: Use local-mac-address instead of mac-address if available Olof Johansson
8 siblings, 0 replies; 10+ messages in thread
From: Olof Johansson @ 2007-05-08 5:47 UTC (permalink / raw)
To: jgarzik; +Cc: netdev
[-- Attachment #1: n-9 --]
[-- Type: text/plain, Size: 5482 bytes --]
PHY support for pasemi_mac.
Signed-off-by: Olof Johansson <olof@lixom.net>
Index: netdev-2.6/drivers/net/pasemi_mac.c
===================================================================
--- netdev-2.6.orig/drivers/net/pasemi_mac.c
+++ netdev-2.6/drivers/net/pasemi_mac.c
@@ -606,6 +606,114 @@ static irqreturn_t pasemi_mac_tx_intr(in
return IRQ_HANDLED;
}
+static void pasemi_adjust_link(struct net_device *dev)
+{
+ struct pasemi_mac *mac = netdev_priv(dev);
+ int msg;
+ unsigned int flags;
+ unsigned int new_flags;
+
+ if (!mac->phydev->link) {
+ /* If no link, MAC speed settings don't matter. Just report
+ * link down and return.
+ */
+ if (mac->link && netif_msg_link(mac))
+ printk(KERN_INFO "%s: Link is down.\n", dev->name);
+
+ netif_carrier_off(dev);
+ mac->link = 0;
+
+ return;
+ } else
+ netif_carrier_on(dev);
+
+ pci_read_config_dword(mac->pdev, PAS_MAC_CFG_PCFG, &flags);
+ new_flags = flags & ~(PAS_MAC_CFG_PCFG_HD | PAS_MAC_CFG_PCFG_SPD_M |
+ PAS_MAC_CFG_PCFG_TSR_M);
+
+ if (!mac->phydev->duplex)
+ new_flags |= PAS_MAC_CFG_PCFG_HD;
+
+ switch (mac->phydev->speed) {
+ case 1000:
+ new_flags |= PAS_MAC_CFG_PCFG_SPD_1G |
+ PAS_MAC_CFG_PCFG_TSR_1G;
+ break;
+ case 100:
+ new_flags |= PAS_MAC_CFG_PCFG_SPD_100M |
+ PAS_MAC_CFG_PCFG_TSR_100M;
+ break;
+ case 10:
+ new_flags |= PAS_MAC_CFG_PCFG_SPD_10M |
+ PAS_MAC_CFG_PCFG_TSR_10M;
+ break;
+ default:
+ printk("Unsupported speed %d\n", mac->phydev->speed);
+ }
+
+ /* Print on link or speed/duplex change */
+ msg = mac->link != mac->phydev->link || flags != new_flags;
+
+ mac->duplex = mac->phydev->duplex;
+ mac->speed = mac->phydev->speed;
+ mac->link = mac->phydev->link;
+
+ if (new_flags != flags)
+ pci_write_config_dword(mac->pdev, PAS_MAC_CFG_PCFG, new_flags);
+
+ if (msg && netif_msg_link(mac))
+ printk(KERN_INFO "%s: Link is up at %d Mbps, %s duplex.\n",
+ dev->name, mac->speed, mac->duplex ? "full" : "half");
+}
+
+static int pasemi_mac_phy_init(struct net_device *dev)
+{
+ struct pasemi_mac *mac = netdev_priv(dev);
+ struct device_node *dn, *phy_dn;
+ struct phy_device *phydev;
+ unsigned int phy_id;
+ const phandle *ph;
+ const unsigned int *prop;
+ struct resource r;
+ int ret;
+
+ dn = pci_device_to_OF_node(mac->pdev);
+ ph = get_property(dn, "phy-handle", NULL);
+ if (!ph)
+ return -ENODEV;
+ phy_dn = of_find_node_by_phandle(*ph);
+
+ prop = get_property(phy_dn, "reg", NULL);
+ ret = of_address_to_resource(phy_dn->parent, 0, &r);
+ if (ret)
+ goto err;
+
+ phy_id = *prop;
+ snprintf(mac->phy_id, BUS_ID_SIZE, PHY_ID_FMT, (int)r.start, phy_id);
+
+ of_node_put(phy_dn);
+
+ mac->link = 0;
+ mac->speed = 0;
+ mac->duplex = -1;
+
+ phydev = phy_connect(dev, mac->phy_id, &pasemi_adjust_link, 0, PHY_INTERFACE_MODE_SGMII);
+
+ if (IS_ERR(phydev)) {
+ printk(KERN_ERR "%s: Could not attach to phy\n", dev->name);
+ return PTR_ERR(phydev);
+ }
+
+ mac->phydev = phydev;
+
+ return 0;
+
+err:
+ of_node_put(phy_dn);
+ return -ENODEV;
+}
+
+
static int pasemi_mac_open(struct net_device *dev)
{
struct pasemi_mac *mac = netdev_priv(dev);
@@ -678,6 +786,13 @@ static int pasemi_mac_open(struct net_de
pasemi_mac_replenish_rx_ring(dev);
+ ret = pasemi_mac_phy_init(dev);
+ /* Some configs don't have PHYs (XAUI etc), so don't complain about
+ * failed init due to -ENODEV.
+ */
+ if (ret && ret != -ENODEV)
+ dev_warn(&mac->pdev->dev, "phy init failed: %d\n", ret);
+
netif_start_queue(dev);
netif_poll_enable(dev);
@@ -708,6 +823,9 @@ static int pasemi_mac_open(struct net_de
goto out_rx_int;
}
+ if (mac->phydev)
+ phy_start(mac->phydev);
+
return 0;
out_rx_int:
@@ -731,6 +849,11 @@ static int pasemi_mac_close(struct net_d
unsigned int stat;
int retries;
+ if (mac->phydev) {
+ phy_stop(mac->phydev);
+ phy_disconnect(mac->phydev);
+ }
+
netif_stop_queue(dev);
/* Clean out any pending buffers */
@@ -1032,6 +1155,9 @@ pasemi_mac_probe(struct pci_dev *pdev, c
else
mac->msg_enable = pasemi_mac_debug;
+ /* Enable most messages by default */
+ mac->msg_enable = (NETIF_MSG_IFUP << 1 ) - 1;
+
err = register_netdev(dev);
if (err) {
Index: netdev-2.6/drivers/net/pasemi_mac.h
===================================================================
--- netdev-2.6.orig/drivers/net/pasemi_mac.h
+++ netdev-2.6/drivers/net/pasemi_mac.h
@@ -24,6 +24,7 @@
#include <linux/ethtool.h>
#include <linux/netdevice.h>
#include <linux/spinlock.h>
+#include <linux/phy.h>
struct pasemi_mac_txring {
spinlock_t lock;
@@ -54,6 +55,7 @@ struct pasemi_mac {
struct pci_dev *pdev;
struct pci_dev *dma_pdev;
struct pci_dev *iob_pdev;
+ struct phy_device *phydev;
struct net_device_stats stats;
/* Pointer to the cacheable per-channel status registers */
@@ -75,8 +77,12 @@ struct pasemi_mac {
struct pasemi_mac_rxring *rx;
unsigned long tx_irq;
unsigned long rx_irq;
+ int link;
+ int speed;
+ int duplex;
unsigned int msg_enable;
+ char phy_id[BUS_ID_SIZE];
};
/* Software status descriptor (desc_info) */
Index: netdev-2.6/drivers/net/Kconfig
===================================================================
--- netdev-2.6.orig/drivers/net/Kconfig
+++ netdev-2.6/drivers/net/Kconfig
@@ -2488,6 +2488,7 @@ config NETXEN_NIC
config PASEMI_MAC
tristate "PA Semi 1/10Gbit MAC"
depends on PPC64 && PCI
+ select PHYLIB
help
This driver supports the on-chip 1/10Gbit Ethernet controller on
PA Semi's PWRficient line of chips.
--
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v4 9/9] pasemi_mac: Use local-mac-address instead of mac-address if available
[not found] <20070508053500.358169000@localhost.localdomain>
` (7 preceding siblings ...)
2007-05-08 5:47 ` [PATCH v4 8/9] pasemi_mac: PHY support Olof Johansson
@ 2007-05-08 5:48 ` Olof Johansson
8 siblings, 0 replies; 10+ messages in thread
From: Olof Johansson @ 2007-05-08 5:48 UTC (permalink / raw)
To: jgarzik; +Cc: netdev
[-- Attachment #1: n-10 --]
[-- Type: text/plain, Size: 766 bytes --]
Use local-mac-address in the device tree instead. Fall back to mac-address
for older firmware.
Signed-off-by: Olof Johansson <olof@lixom.net>
Index: netdev-2.6/drivers/net/pasemi_mac.c
===================================================================
--- netdev-2.6.orig/drivers/net/pasemi_mac.c
+++ netdev-2.6/drivers/net/pasemi_mac.c
@@ -94,7 +94,12 @@ static int pasemi_get_mac_addr(struct pa
return -ENOENT;
}
- maddr = get_property(dn, "mac-address", NULL);
+ maddr = get_property(dn, "local-mac-address", NULL);
+
+ /* Fall back to mac-address for older firmware */
+ if (maddr == NULL)
+ maddr = get_property(dn, "mac-address", NULL);
+
if (maddr == NULL) {
dev_warn(&pdev->dev,
"no mac address in device tree, not configuring\n");
--
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v4 1/9] pasemi_mac: Move the IRQ mapping from the PCI layer to the driver
2007-05-08 5:47 ` [PATCH v4 1/9] pasemi_mac: Move the IRQ mapping from the PCI layer to the driver Olof Johansson
@ 2007-05-08 5:48 ` Jeff Garzik
0 siblings, 0 replies; 10+ messages in thread
From: Jeff Garzik @ 2007-05-08 5:48 UTC (permalink / raw)
To: Olof Johansson; +Cc: netdev
Olof Johansson wrote:
> Fixes for ethernet IRQ mapping, to be done in the driver instead of in
> the platform setup code.
>
> Signed-off-by: Olof Johansson <olof@lixom.net>
applied 1-9
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2007-05-08 6:08 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20070508053500.358169000@localhost.localdomain>
2007-05-08 5:47 ` [PATCH v4 1/9] pasemi_mac: Move the IRQ mapping from the PCI layer to the driver Olof Johansson
2007-05-08 5:48 ` Jeff Garzik
2007-05-08 5:47 ` [PATCH v4 2/9] pasemi_mac: Abstract and fix up interrupt restart routines Olof Johansson
2007-05-08 5:47 ` [PATCH v4 3/9] pasemi_mac: Timer and interrupt fixes Olof Johansson
2007-05-08 5:47 ` [PATCH v4 4/9] pasemi_mac: Add SKB reuse / copy-break Olof Johansson
2007-05-08 5:47 ` [PATCH v4 5/9] pasemi_mac: Minor cleanup / define fixes Olof Johansson
2007-05-08 5:47 ` [PATCH v4 6/9] pasemi_mac: Logic cleanup / rx performance improvements Olof Johansson
2007-05-08 5:47 ` [PATCH v4 7/9] pasemi_mac: Add msglevel support and "debug" module param Olof Johansson
2007-05-08 5:47 ` [PATCH v4 8/9] pasemi_mac: PHY support Olof Johansson
2007-05-08 5:48 ` [PATCH v4 9/9] pasemi_mac: Use local-mac-address instead of mac-address if available Olof Johansson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).