* [PATCH] [01/10] pasemi_mac: Abstract out register access
[not found] <20070817205413.548020000@lixom.net>
@ 2007-08-22 14:12 ` Olof Johansson
2007-08-31 13:50 ` Jeff Garzik
2007-08-22 14:12 ` [PATCH] [02/10] pasemi_mac: Stop using the pci config space accessors for register read/writes Olof Johansson
` (8 subsequent siblings)
9 siblings, 1 reply; 18+ messages in thread
From: Olof Johansson @ 2007-08-22 14:12 UTC (permalink / raw)
To: jgarzik; +Cc: netdev, linuxppc-dev
Abstract out the PCI config read/write accesses into reg read/write ones,
still calling the pci accessors on the back end.
Signed-off-by: Olof Johansson <olof@lixom.net>
Index: mainline/drivers/net/pasemi_mac.c
===================================================================
--- mainline.orig/drivers/net/pasemi_mac.c
+++ mainline/drivers/net/pasemi_mac.c
@@ -81,6 +81,48 @@ MODULE_PARM_DESC(debug, "PA Semi MAC bit
static struct pasdma_status *dma_status;
+static unsigned int read_iob_reg(struct pasemi_mac *mac, unsigned int reg)
+{
+ unsigned int val;
+
+ pci_read_config_dword(mac->iob_pdev, reg, &val);
+ return val;
+}
+
+static void write_iob_reg(struct pasemi_mac *mac, unsigned int reg,
+ unsigned int val)
+{
+ pci_write_config_dword(mac->iob_pdev, reg, val);
+}
+
+static unsigned int read_mac_reg(struct pasemi_mac *mac, unsigned int reg)
+{
+ unsigned int val;
+
+ pci_read_config_dword(mac->pdev, reg, &val);
+ return val;
+}
+
+static void write_mac_reg(struct pasemi_mac *mac, unsigned int reg,
+ unsigned int val)
+{
+ pci_write_config_dword(mac->pdev, reg, val);
+}
+
+static unsigned int read_dma_reg(struct pasemi_mac *mac, unsigned int reg)
+{
+ unsigned int val;
+
+ pci_read_config_dword(mac->dma_pdev, reg, &val);
+ return val;
+}
+
+static void write_dma_reg(struct pasemi_mac *mac, unsigned int reg,
+ unsigned int val)
+{
+ pci_write_config_dword(mac->dma_pdev, reg, val);
+}
+
static int pasemi_get_mac_addr(struct pasemi_mac *mac)
{
struct pci_dev *pdev = mac->pdev;
@@ -166,22 +208,21 @@ static int pasemi_mac_setup_rx_resources
memset(ring->buffers, 0, RX_RING_SIZE * sizeof(u64));
- pci_write_config_dword(mac->dma_pdev, PAS_DMA_RXCHAN_BASEL(chan_id),
- PAS_DMA_RXCHAN_BASEL_BRBL(ring->dma));
+ write_dma_reg(mac, PAS_DMA_RXCHAN_BASEL(chan_id), PAS_DMA_RXCHAN_BASEL_BRBL(ring->dma));
+
+ write_dma_reg(mac, PAS_DMA_RXCHAN_BASEU(chan_id),
+ PAS_DMA_RXCHAN_BASEU_BRBH(ring->dma >> 32) |
+ PAS_DMA_RXCHAN_BASEU_SIZ(RX_RING_SIZE >> 2));
+
+ write_dma_reg(mac, PAS_DMA_RXCHAN_CFG(chan_id),
+ PAS_DMA_RXCHAN_CFG_HBU(1));
- pci_write_config_dword(mac->dma_pdev, PAS_DMA_RXCHAN_BASEU(chan_id),
- PAS_DMA_RXCHAN_BASEU_BRBH(ring->dma >> 32) |
- PAS_DMA_RXCHAN_BASEU_SIZ(RX_RING_SIZE >> 2));
-
- pci_write_config_dword(mac->dma_pdev, PAS_DMA_RXCHAN_CFG(chan_id),
- PAS_DMA_RXCHAN_CFG_HBU(1));
-
- pci_write_config_dword(mac->dma_pdev, PAS_DMA_RXINT_BASEL(mac->dma_if),
- PAS_DMA_RXINT_BASEL_BRBL(__pa(ring->buffers)));
-
- pci_write_config_dword(mac->dma_pdev, PAS_DMA_RXINT_BASEU(mac->dma_if),
- PAS_DMA_RXINT_BASEU_BRBH(__pa(ring->buffers) >> 32) |
- PAS_DMA_RXINT_BASEU_SIZ(RX_RING_SIZE >> 3));
+ write_dma_reg(mac, PAS_DMA_RXINT_BASEL(mac->dma_if),
+ PAS_DMA_RXINT_BASEL_BRBL(__pa(ring->buffers)));
+
+ write_dma_reg(mac, PAS_DMA_RXINT_BASEU(mac->dma_if),
+ PAS_DMA_RXINT_BASEU_BRBH(__pa(ring->buffers) >> 32) |
+ PAS_DMA_RXINT_BASEU_SIZ(RX_RING_SIZE >> 3));
ring->next_to_fill = 0;
ring->next_to_clean = 0;
@@ -233,18 +274,18 @@ static int pasemi_mac_setup_tx_resources
memset(ring->desc, 0, TX_RING_SIZE * sizeof(struct pas_dma_xct_descr));
- pci_write_config_dword(mac->dma_pdev, PAS_DMA_TXCHAN_BASEL(chan_id),
- PAS_DMA_TXCHAN_BASEL_BRBL(ring->dma));
+ write_dma_reg(mac, PAS_DMA_TXCHAN_BASEL(chan_id),
+ PAS_DMA_TXCHAN_BASEL_BRBL(ring->dma));
val = PAS_DMA_TXCHAN_BASEU_BRBH(ring->dma >> 32);
val |= PAS_DMA_TXCHAN_BASEU_SIZ(TX_RING_SIZE >> 2);
- pci_write_config_dword(mac->dma_pdev, PAS_DMA_TXCHAN_BASEU(chan_id), val);
+ write_dma_reg(mac, PAS_DMA_TXCHAN_BASEU(chan_id), val);
- pci_write_config_dword(mac->dma_pdev, PAS_DMA_TXCHAN_CFG(chan_id),
- PAS_DMA_TXCHAN_CFG_TY_IFACE |
- PAS_DMA_TXCHAN_CFG_TATTR(mac->dma_if) |
- PAS_DMA_TXCHAN_CFG_UP |
- PAS_DMA_TXCHAN_CFG_WT(2));
+ write_dma_reg(mac, PAS_DMA_TXCHAN_CFG(chan_id),
+ PAS_DMA_TXCHAN_CFG_TY_IFACE |
+ PAS_DMA_TXCHAN_CFG_TATTR(mac->dma_if) |
+ PAS_DMA_TXCHAN_CFG_UP |
+ PAS_DMA_TXCHAN_CFG_WT(2));
ring->next_to_use = 0;
ring->next_to_clean = 0;
@@ -383,12 +424,8 @@ static void pasemi_mac_replenish_rx_ring
wmb();
- pci_write_config_dword(mac->dma_pdev,
- PAS_DMA_RXCHAN_INCR(mac->dma_rxch),
- limit - count);
- pci_write_config_dword(mac->dma_pdev,
- PAS_DMA_RXINT_INCR(mac->dma_if),
- limit - count);
+ write_dma_reg(mac, PAS_DMA_RXCHAN_INCR(mac->dma_rxch), limit - count);
+ write_dma_reg(mac, PAS_DMA_RXINT_INCR(mac->dma_if), limit - count);
mac->rx->next_to_fill += limit - count;
}
@@ -404,9 +441,7 @@ static void pasemi_mac_restart_rx_intr(s
reg = PAS_IOB_DMA_RXCH_RESET_PCNT(pcnt) | PAS_IOB_DMA_RXCH_RESET_PINTC;
- pci_write_config_dword(mac->iob_pdev,
- PAS_IOB_DMA_RXCH_RESET(mac->dma_rxch),
- reg);
+ write_iob_reg(mac, PAS_IOB_DMA_RXCH_RESET(mac->dma_rxch), reg);
}
static void pasemi_mac_restart_tx_intr(struct pasemi_mac *mac)
@@ -418,8 +453,7 @@ static void pasemi_mac_restart_tx_intr(s
reg = PAS_IOB_DMA_TXCH_RESET_PCNT(pcnt) | PAS_IOB_DMA_TXCH_RESET_PINTC;
- pci_write_config_dword(mac->iob_pdev,
- PAS_IOB_DMA_TXCH_RESET(mac->dma_txch), reg);
+ write_iob_reg(mac, PAS_IOB_DMA_TXCH_RESET(mac->dma_txch), reg);
}
@@ -574,8 +608,6 @@ static irqreturn_t pasemi_mac_rx_intr(in
* all others.
*/
- pci_read_config_dword(mac->dma_pdev, PAS_DMA_RXINT_RCMDSTA(mac->dma_if), ®);
-
reg = 0;
if (*mac->rx_status & PAS_STATUS_SOFT)
reg |= PAS_IOB_DMA_RXCH_RESET_SINTC;
@@ -586,9 +618,7 @@ static irqreturn_t pasemi_mac_rx_intr(in
netif_rx_schedule(dev);
- pci_write_config_dword(mac->iob_pdev,
- PAS_IOB_DMA_RXCH_RESET(mac->dma_rxch), reg);
-
+ write_iob_reg(mac, PAS_IOB_DMA_RXCH_RESET(mac->dma_rxch), reg);
return IRQ_HANDLED;
}
@@ -613,9 +643,7 @@ static irqreturn_t pasemi_mac_tx_intr(in
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);
+ write_iob_reg(mac, PAS_IOB_DMA_TXCH_RESET(mac->dma_txch), reg);
return IRQ_HANDLED;
}
@@ -641,7 +669,7 @@ static void pasemi_adjust_link(struct ne
} else
netif_carrier_on(dev);
- pci_read_config_dword(mac->pdev, PAS_MAC_CFG_PCFG, &flags);
+ flags = read_mac_reg(mac, PAS_MAC_CFG_PCFG);
new_flags = flags & ~(PAS_MAC_CFG_PCFG_HD | PAS_MAC_CFG_PCFG_SPD_M |
PAS_MAC_CFG_PCFG_TSR_M);
@@ -673,7 +701,7 @@ static void pasemi_adjust_link(struct ne
mac->link = mac->phydev->link;
if (new_flags != flags)
- pci_write_config_dword(mac->pdev, PAS_MAC_CFG_PCFG, new_flags);
+ write_mac_reg(mac, 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",
@@ -736,39 +764,37 @@ static int pasemi_mac_open(struct net_de
int ret;
/* enable rx section */
- pci_write_config_dword(mac->dma_pdev, PAS_DMA_COM_RXCMD,
- PAS_DMA_COM_RXCMD_EN);
+ write_dma_reg(mac, PAS_DMA_COM_RXCMD, PAS_DMA_COM_RXCMD_EN);
/* enable tx section */
- pci_write_config_dword(mac->dma_pdev, PAS_DMA_COM_TXCMD,
- PAS_DMA_COM_TXCMD_EN);
+ write_dma_reg(mac, PAS_DMA_COM_TXCMD, PAS_DMA_COM_TXCMD_EN);
flags = PAS_MAC_CFG_TXP_FCE | PAS_MAC_CFG_TXP_FPC(3) |
PAS_MAC_CFG_TXP_SL(3) | PAS_MAC_CFG_TXP_COB(0xf) |
PAS_MAC_CFG_TXP_TIFT(8) | PAS_MAC_CFG_TXP_TIFG(12);
- pci_write_config_dword(mac->pdev, PAS_MAC_CFG_TXP, flags);
+ write_mac_reg(mac, PAS_MAC_CFG_TXP, flags);
flags = PAS_MAC_CFG_PCFG_S1 | PAS_MAC_CFG_PCFG_PE |
PAS_MAC_CFG_PCFG_PR | PAS_MAC_CFG_PCFG_CE;
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(0));
+ write_iob_reg(mac, PAS_IOB_DMA_RXCH_CFG(mac->dma_rxch),
+ PAS_IOB_DMA_RXCH_CFG_CNTTH(0));
- pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_TXCH_CFG(mac->dma_txch),
- PAS_IOB_DMA_TXCH_CFG_CNTTH(32));
+ write_iob_reg(mac, 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(0xffffff));
+ write_iob_reg(mac, PAS_IOB_DMA_COM_TIMEOUTCFG,
+ PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(0xffffff));
- pci_write_config_dword(mac->pdev, PAS_MAC_CFG_PCFG, flags);
+ write_mac_reg(mac, PAS_MAC_CFG_PCFG, flags);
ret = pasemi_mac_setup_rx_resources(dev);
if (ret)
@@ -778,25 +804,22 @@ static int pasemi_mac_open(struct net_de
if (ret)
goto out_tx_resources;
- pci_write_config_dword(mac->pdev, PAS_MAC_IPC_CHNL,
- PAS_MAC_IPC_CHNL_DCHNO(mac->dma_rxch) |
- PAS_MAC_IPC_CHNL_BCH(mac->dma_rxch));
+ write_mac_reg(mac, PAS_MAC_IPC_CHNL,
+ PAS_MAC_IPC_CHNL_DCHNO(mac->dma_rxch) |
+ PAS_MAC_IPC_CHNL_BCH(mac->dma_rxch));
/* enable rx if */
- pci_write_config_dword(mac->dma_pdev,
- PAS_DMA_RXINT_RCMDSTA(mac->dma_if),
- PAS_DMA_RXINT_RCMDSTA_EN);
+ write_dma_reg(mac, PAS_DMA_RXINT_RCMDSTA(mac->dma_if),
+ PAS_DMA_RXINT_RCMDSTA_EN);
/* enable rx channel */
- pci_write_config_dword(mac->dma_pdev,
- PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch),
- PAS_DMA_RXCHAN_CCMDSTA_EN |
- PAS_DMA_RXCHAN_CCMDSTA_DU);
+ write_dma_reg(mac, PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch),
+ PAS_DMA_RXCHAN_CCMDSTA_EN |
+ PAS_DMA_RXCHAN_CCMDSTA_DU);
/* enable tx channel */
- pci_write_config_dword(mac->dma_pdev,
- PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch),
- PAS_DMA_TXCHAN_TCMDSTA_EN);
+ write_dma_reg(mac, PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch),
+ PAS_DMA_TXCHAN_TCMDSTA_EN);
pasemi_mac_replenish_rx_ring(dev);
@@ -875,20 +898,12 @@ static int pasemi_mac_close(struct net_d
pasemi_mac_clean_rx(mac, RX_RING_SIZE);
/* Disable interface */
- pci_write_config_dword(mac->dma_pdev,
- PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch),
- PAS_DMA_TXCHAN_TCMDSTA_ST);
- pci_write_config_dword(mac->dma_pdev,
- PAS_DMA_RXINT_RCMDSTA(mac->dma_if),
- PAS_DMA_RXINT_RCMDSTA_ST);
- pci_write_config_dword(mac->dma_pdev,
- PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch),
- PAS_DMA_RXCHAN_CCMDSTA_ST);
+ write_dma_reg(mac, PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch), PAS_DMA_TXCHAN_TCMDSTA_ST);
+ write_dma_reg(mac, PAS_DMA_RXINT_RCMDSTA(mac->dma_if), PAS_DMA_RXINT_RCMDSTA_ST);
+ write_dma_reg(mac, PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch), PAS_DMA_RXCHAN_CCMDSTA_ST);
for (retries = 0; retries < MAX_RETRIES; retries++) {
- pci_read_config_dword(mac->dma_pdev,
- PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch),
- &stat);
+ stat = read_dma_reg(mac, PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch));
if (!(stat & PAS_DMA_TXCHAN_TCMDSTA_ACT))
break;
cond_resched();
@@ -898,9 +913,7 @@ static int pasemi_mac_close(struct net_d
dev_err(&mac->dma_pdev->dev, "Failed to stop tx channel\n");
for (retries = 0; retries < MAX_RETRIES; retries++) {
- pci_read_config_dword(mac->dma_pdev,
- PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch),
- &stat);
+ stat = read_dma_reg(mac, PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch));
if (!(stat & PAS_DMA_RXCHAN_CCMDSTA_ACT))
break;
cond_resched();
@@ -910,9 +923,7 @@ static int pasemi_mac_close(struct net_d
dev_err(&mac->dma_pdev->dev, "Failed to stop rx channel\n");
for (retries = 0; retries < MAX_RETRIES; retries++) {
- pci_read_config_dword(mac->dma_pdev,
- PAS_DMA_RXINT_RCMDSTA(mac->dma_if),
- &stat);
+ stat = read_dma_reg(mac, PAS_DMA_RXINT_RCMDSTA(mac->dma_if));
if (!(stat & PAS_DMA_RXINT_RCMDSTA_ACT))
break;
cond_resched();
@@ -925,12 +936,9 @@ static int pasemi_mac_close(struct net_d
* stopping, since you can't disable when active.
*/
- pci_write_config_dword(mac->dma_pdev,
- PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch), 0);
- pci_write_config_dword(mac->dma_pdev,
- PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch), 0);
- pci_write_config_dword(mac->dma_pdev,
- PAS_DMA_RXINT_RCMDSTA(mac->dma_if), 0);
+ write_dma_reg(mac, PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch), 0);
+ write_dma_reg(mac, PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch), 0);
+ write_dma_reg(mac, PAS_DMA_RXINT_RCMDSTA(mac->dma_if), 0);
free_irq(mac->tx_irq, dev);
free_irq(mac->rx_irq, dev);
@@ -1011,8 +1019,7 @@ static int pasemi_mac_start_tx(struct sk
spin_unlock_irqrestore(&txring->lock, flags);
- pci_write_config_dword(mac->dma_pdev,
- PAS_DMA_TXCHAN_INCR(mac->dma_txch), 1);
+ write_dma_reg(mac, PAS_DMA_TXCHAN_INCR(mac->dma_txch), 1);
return NETDEV_TX_OK;
@@ -1035,7 +1042,7 @@ static void pasemi_mac_set_rx_mode(struc
struct pasemi_mac *mac = netdev_priv(dev);
unsigned int flags;
- pci_read_config_dword(mac->pdev, PAS_MAC_CFG_PCFG, &flags);
+ flags = read_mac_reg(mac, PAS_MAC_CFG_PCFG);
/* Set promiscuous */
if (dev->flags & IFF_PROMISC)
@@ -1043,7 +1050,7 @@ static void pasemi_mac_set_rx_mode(struc
else
flags &= ~PAS_MAC_CFG_PCFG_PR;
- pci_write_config_dword(mac->pdev, PAS_MAC_CFG_PCFG, flags);
+ write_mac_reg(mac, PAS_MAC_CFG_PCFG, flags);
}
--
^ permalink raw reply [flat|nested] 18+ messages in thread* [PATCH] [02/10] pasemi_mac: Stop using the pci config space accessors for register read/writes
[not found] <20070817205413.548020000@lixom.net>
2007-08-22 14:12 ` [PATCH] [01/10] pasemi_mac: Abstract out register access Olof Johansson
@ 2007-08-22 14:12 ` Olof Johansson
2007-08-23 0:31 ` Stephen Rothwell
2007-08-23 18:13 ` [PATCH v2] " Olof Johansson
2007-08-22 14:12 ` [PATCH] [03/10] pasemi_mac: Enable L2 caching of packet headers Olof Johansson
` (7 subsequent siblings)
9 siblings, 2 replies; 18+ messages in thread
From: Olof Johansson @ 2007-08-22 14:12 UTC (permalink / raw)
To: jgarzik; +Cc: netdev, linuxppc-dev
Move away from using the pci config access functions for simple register
access. Our device has all of the registers in the config space (hey,
from the hardware point of view it looks reasonable :-), so we need to
somehow get to it. Newer firmwares have it in the device tree such that
we can just get it and ioremap it there (in case it ever moves in future
products). For now, provide a hardcoded fallback for older firmwares.
Signed-off-by: Olof Johansson <olof@lixom.net>
Index: mainline/drivers/net/pasemi_mac.c
===================================================================
--- mainline.orig/drivers/net/pasemi_mac.c
+++ mainline/drivers/net/pasemi_mac.c
@@ -81,46 +81,47 @@ MODULE_PARM_DESC(debug, "PA Semi MAC bit
static struct pasdma_status *dma_status;
-static unsigned int read_iob_reg(struct pasemi_mac *mac, unsigned int reg)
+static inline unsigned int read_iob_reg(struct pasemi_mac *mac, unsigned int reg)
{
unsigned int val;
- pci_read_config_dword(mac->iob_pdev, reg, &val);
+ val = in_le32(mac->iob_regs+reg);
+
return val;
}
-static void write_iob_reg(struct pasemi_mac *mac, unsigned int reg,
+static inline void write_iob_reg(struct pasemi_mac *mac, unsigned int reg,
unsigned int val)
{
- pci_write_config_dword(mac->iob_pdev, reg, val);
+ out_le32(mac->iob_regs+reg, val);
}
-static unsigned int read_mac_reg(struct pasemi_mac *mac, unsigned int reg)
+static inline unsigned int read_mac_reg(struct pasemi_mac *mac, unsigned int reg)
{
unsigned int val;
- pci_read_config_dword(mac->pdev, reg, &val);
+ val = in_le32(mac->regs+reg);
return val;
}
-static void write_mac_reg(struct pasemi_mac *mac, unsigned int reg,
+static inline void write_mac_reg(struct pasemi_mac *mac, unsigned int reg,
unsigned int val)
{
- pci_write_config_dword(mac->pdev, reg, val);
+ out_le32(mac->regs+reg, val);
}
-static unsigned int read_dma_reg(struct pasemi_mac *mac, unsigned int reg)
+static inline unsigned int read_dma_reg(struct pasemi_mac *mac, unsigned int reg)
{
unsigned int val;
- pci_read_config_dword(mac->dma_pdev, reg, &val);
+ val = in_le32(mac->dma_regs+reg);
return val;
}
-static void write_dma_reg(struct pasemi_mac *mac, unsigned int reg,
+static inline void write_dma_reg(struct pasemi_mac *mac, unsigned int reg,
unsigned int val)
{
- pci_write_config_dword(mac->dma_pdev, reg, val);
+ out_le32(mac->dma_regs+reg, val);
}
static int pasemi_get_mac_addr(struct pasemi_mac *mac)
@@ -585,7 +586,6 @@ static int pasemi_mac_clean_tx(struct pa
}
mac->tx->next_to_clean += count;
spin_unlock_irqrestore(&mac->tx->lock, flags);
-
netif_wake_queue(mac->netdev);
return count;
@@ -1076,6 +1076,73 @@ static int pasemi_mac_poll(struct net_de
}
}
+static inline void __iomem * __devinit map_onedev(struct pci_dev *p, int index)
+{
+ struct device_node *dn;
+ void __iomem *ret;
+
+ dn = pci_device_to_OF_node(p);
+ if (!dn)
+ goto fallback;
+
+ ret = of_iomap(dn, index);
+ if (!ret)
+ goto fallback;
+
+ return ret;
+fallback:
+ /* This is hardcoded and ugly, but we have some firmware versions
+ * who don't provide the register space in the device tree. Luckily
+ * they are at well-known locations so we can just do the math here.
+ */
+ return ioremap(0xe0000000 + (p->devfn << 12), 0x2000);
+}
+
+static int __devinit pasemi_mac_map_regs(struct pasemi_mac *mac)
+{
+ struct resource res;
+ struct device_node *dn;
+ int err;
+
+ mac->dma_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa007, NULL);
+ if (!mac->dma_pdev) {
+ dev_err(&mac->pdev->dev, "Can't find DMA Controller\n");
+ return -ENODEV;
+ }
+
+ mac->iob_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa001, NULL);
+ if (!mac->iob_pdev) {
+ dev_err(&mac->pdev->dev, "Can't find I/O Bridge\n");
+ return -ENODEV;
+ }
+
+ mac->regs = map_onedev(mac->pdev, 0);
+ mac->dma_regs = map_onedev(mac->dma_pdev, 0);
+ mac->iob_regs = map_onedev(mac->iob_pdev, 0);
+
+ if (!mac->regs || !mac->dma_regs || !mac->iob_regs) {
+ dev_err(&mac->pdev->dev, "Can't map registers\n");
+ return -ENODEV;
+ }
+
+ /* The dma status structure is located in the I/O bridge, and
+ * is cache coherent.
+ */
+ if (!dma_status) {
+ dn = pci_device_to_OF_node(mac->iob_pdev);
+ if (dn)
+ err = of_address_to_resource(dn, 1, &res);
+ if (!dn || err) {
+ /* Fallback for old firmware */
+ res.start = 0xfd800000;
+ res.end = res.start + 0x1000;
+ }
+ dma_status = __ioremap(res.start, res.end-res.start, 0);
+ }
+
+ return 0;
+}
+
static int __devinit
pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
@@ -1104,21 +1171,6 @@ pasemi_mac_probe(struct pci_dev *pdev, c
mac->pdev = pdev;
mac->netdev = dev;
- mac->dma_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa007, NULL);
-
- if (!mac->dma_pdev) {
- dev_err(&pdev->dev, "Can't find DMA Controller\n");
- err = -ENODEV;
- goto out_free_netdev;
- }
-
- mac->iob_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa001, NULL);
-
- if (!mac->iob_pdev) {
- dev_err(&pdev->dev, "Can't find I/O Bridge\n");
- err = -ENODEV;
- goto out_put_dma_pdev;
- }
/* These should come out of the device tree eventually */
mac->dma_txch = index;
@@ -1161,12 +1213,9 @@ pasemi_mac_probe(struct pci_dev *pdev, c
dev->poll = pasemi_mac_poll;
dev->features = NETIF_F_HW_CSUM;
- /* The dma status structure is located in the I/O bridge, and
- * is cache coherent.
- */
- if (!dma_status)
- /* XXXOJN This should come from the device tree */
- dma_status = __ioremap(0xfd800000, 0x1000, 0);
+ err = pasemi_mac_map_regs(mac);
+ if (err)
+ goto out;
mac->rx_status = &dma_status->rx_sta[mac->dma_rxch];
mac->tx_status = &dma_status->tx_sta[mac->dma_txch];
@@ -1193,10 +1242,17 @@ pasemi_mac_probe(struct pci_dev *pdev, c
return err;
out:
- pci_dev_put(mac->iob_pdev);
-out_put_dma_pdev:
- pci_dev_put(mac->dma_pdev);
-out_free_netdev:
+ if (mac->iob_pdev)
+ pci_dev_put(mac->iob_pdev);
+ if (mac->dma_pdev)
+ pci_dev_put(mac->dma_pdev);
+ if (mac->dma_regs)
+ iounmap(mac->dma_regs);
+ if (mac->iob_regs)
+ iounmap(mac->iob_regs);
+ if (mac->regs)
+ iounmap(mac->regs);
+
free_netdev(dev);
out_disable_device:
pci_disable_device(pdev);
@@ -1220,6 +1276,10 @@ static void __devexit pasemi_mac_remove(
pci_dev_put(mac->dma_pdev);
pci_dev_put(mac->iob_pdev);
+ iounmap(mac->regs);
+ iounmap(mac->dma_regs);
+ iounmap(mac->iob_regs);
+
pci_set_drvdata(pdev, NULL);
free_netdev(netdev);
}
Index: mainline/drivers/net/pasemi_mac.h
===================================================================
--- mainline.orig/drivers/net/pasemi_mac.h
+++ mainline/drivers/net/pasemi_mac.h
@@ -52,6 +52,9 @@ struct pasemi_mac_rxring {
struct pasemi_mac {
struct net_device *netdev;
+ void __iomem *regs;
+ void __iomem *dma_regs;
+ void __iomem *iob_regs;
struct pci_dev *pdev;
struct pci_dev *dma_pdev;
struct pci_dev *iob_pdev;
--
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH] [02/10] pasemi_mac: Stop using the pci config space accessors for register read/writes
2007-08-22 14:12 ` [PATCH] [02/10] pasemi_mac: Stop using the pci config space accessors for register read/writes Olof Johansson
@ 2007-08-23 0:31 ` Stephen Rothwell
2007-08-23 18:12 ` Olof Johansson
2007-08-23 18:13 ` [PATCH v2] " Olof Johansson
1 sibling, 1 reply; 18+ messages in thread
From: Stephen Rothwell @ 2007-08-23 0:31 UTC (permalink / raw)
To: Olof Johansson; +Cc: netdev, jgarzik, linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 1112 bytes --]
Hi Olof,
On Wed, 22 Aug 2007 09:12:48 -0500 Olof Johansson <olof@lixom.net> wrote:
>
> -static unsigned int read_iob_reg(struct pasemi_mac *mac, unsigned int reg)
> +static inline unsigned int read_iob_reg(struct pasemi_mac *mac, unsigned int reg)
^^^^^^
For static functions in C files, we tend not to bother marking them
inline any more as the compiler does a pretty good job theses days.
> {
> unsigned int val;
>
> - pci_read_config_dword(mac->iob_pdev, reg, &val);
> + val = in_le32(mac->iob_regs+reg);
> +
> return val;
Why not just "return in_le32(mac->iob_regs+reg);" ?
And similarly below?
> +static inline void __iomem * __devinit map_onedev(struct pci_dev *p, int index)
^^^^^^ ^^^^^^^^^
Mixing inline and __*init is just plain silly :-)
> +fallback:
> + /* This is hardcoded and ugly, but we have some firmware versions
> + * who don't provide the register space in the device tree. Luckily
^^^
"that"
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH] [02/10] pasemi_mac: Stop using the pci config space accessors for register read/writes
2007-08-23 0:31 ` Stephen Rothwell
@ 2007-08-23 18:12 ` Olof Johansson
0 siblings, 0 replies; 18+ messages in thread
From: Olof Johansson @ 2007-08-23 18:12 UTC (permalink / raw)
To: Stephen Rothwell; +Cc: netdev, jgarzik, linuxppc-dev
On Thu, Aug 23, 2007 at 10:31:03AM +1000, Stephen Rothwell wrote:
> On Wed, 22 Aug 2007 09:12:48 -0500 Olof Johansson <olof@lixom.net> wrote:
> >
> > -static unsigned int read_iob_reg(struct pasemi_mac *mac, unsigned int reg)
> > +static inline unsigned int read_iob_reg(struct pasemi_mac *mac, unsigned int reg)
> ^^^^^^
> For static functions in C files, we tend not to bother marking them
> inline any more as the compiler does a pretty good job theses days.
Yeah, sloppy coding on my behalf. It was still there from when I
explicitly added noinline during debugging, forgot to take it out
alltogether.
> > - pci_read_config_dword(mac->iob_pdev, reg, &val);
> > + val = in_le32(mac->iob_regs+reg);
> > +
> > return val;
>
> Why not just "return in_le32(mac->iob_regs+reg);" ?
> And similarly below?
Residual from debugging as well, I had debug hooks showing what was
read/written that I took out, but didn't fix up the surrounding stuff.
Refreshed patch posted separately. Thanks for the feedback.
-Olof
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v2] [02/10] pasemi_mac: Stop using the pci config space accessors for register read/writes
2007-08-22 14:12 ` [PATCH] [02/10] pasemi_mac: Stop using the pci config space accessors for register read/writes Olof Johansson
2007-08-23 0:31 ` Stephen Rothwell
@ 2007-08-23 18:13 ` Olof Johansson
2007-08-24 4:05 ` Stephen Rothwell
2007-08-31 13:54 ` Jeff Garzik
1 sibling, 2 replies; 18+ messages in thread
From: Olof Johansson @ 2007-08-23 18:13 UTC (permalink / raw)
To: jgarzik; +Cc: netdev, linuxppc-dev
Move away from using the pci config access functions for simple register
access. Our device has all of the registers in the config space (hey,
from the hardware point of view it looks reasonable :-), so we need to
somehow get to it. Newer firmwares have it in the device tree such that
we can just get it and ioremap it there (in case it ever moves in future
products). For now, provide a hardcoded fallback for older firmwares.
Signed-off-by: Olof Johansson <olof@lixom.net>
---
Updated: Removed explicit inlines, cleaned up read functions, fixed
grammar.
Index: mainline/drivers/net/pasemi_mac.c
===================================================================
--- mainline.orig/drivers/net/pasemi_mac.c
+++ mainline/drivers/net/pasemi_mac.c
@@ -83,44 +83,35 @@ static struct pasdma_status *dma_status;
static unsigned int read_iob_reg(struct pasemi_mac *mac, unsigned int reg)
{
- unsigned int val;
-
- pci_read_config_dword(mac->iob_pdev, reg, &val);
- return val;
+ return in_le32(mac->iob_regs+reg);
}
static void write_iob_reg(struct pasemi_mac *mac, unsigned int reg,
unsigned int val)
{
- pci_write_config_dword(mac->iob_pdev, reg, val);
+ out_le32(mac->iob_regs+reg, val);
}
static unsigned int read_mac_reg(struct pasemi_mac *mac, unsigned int reg)
{
- unsigned int val;
-
- pci_read_config_dword(mac->pdev, reg, &val);
- return val;
+ return in_le32(mac->regs+reg);
}
static void write_mac_reg(struct pasemi_mac *mac, unsigned int reg,
unsigned int val)
{
- pci_write_config_dword(mac->pdev, reg, val);
+ out_le32(mac->regs+reg, val);
}
static unsigned int read_dma_reg(struct pasemi_mac *mac, unsigned int reg)
{
- unsigned int val;
-
- pci_read_config_dword(mac->dma_pdev, reg, &val);
- return val;
+ return in_le32(mac->dma_regs+reg);
}
static void write_dma_reg(struct pasemi_mac *mac, unsigned int reg,
unsigned int val)
{
- pci_write_config_dword(mac->dma_pdev, reg, val);
+ out_le32(mac->dma_regs+reg, val);
}
static int pasemi_get_mac_addr(struct pasemi_mac *mac)
@@ -585,7 +576,6 @@ static int pasemi_mac_clean_tx(struct pa
}
mac->tx->next_to_clean += count;
spin_unlock_irqrestore(&mac->tx->lock, flags);
-
netif_wake_queue(mac->netdev);
return count;
@@ -1076,6 +1066,73 @@ static int pasemi_mac_poll(struct net_de
}
}
+static void __iomem * __devinit map_onedev(struct pci_dev *p, int index)
+{
+ struct device_node *dn;
+ void __iomem *ret;
+
+ dn = pci_device_to_OF_node(p);
+ if (!dn)
+ goto fallback;
+
+ ret = of_iomap(dn, index);
+ if (!ret)
+ goto fallback;
+
+ return ret;
+fallback:
+ /* This is hardcoded and ugly, but we have some firmware versions
+ * that don't provide the register space in the device tree. Luckily
+ * they are at well-known locations so we can just do the math here.
+ */
+ return ioremap(0xe0000000 + (p->devfn << 12), 0x2000);
+}
+
+static int __devinit pasemi_mac_map_regs(struct pasemi_mac *mac)
+{
+ struct resource res;
+ struct device_node *dn;
+ int err;
+
+ mac->dma_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa007, NULL);
+ if (!mac->dma_pdev) {
+ dev_err(&mac->pdev->dev, "Can't find DMA Controller\n");
+ return -ENODEV;
+ }
+
+ mac->iob_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa001, NULL);
+ if (!mac->iob_pdev) {
+ dev_err(&mac->pdev->dev, "Can't find I/O Bridge\n");
+ return -ENODEV;
+ }
+
+ mac->regs = map_onedev(mac->pdev, 0);
+ mac->dma_regs = map_onedev(mac->dma_pdev, 0);
+ mac->iob_regs = map_onedev(mac->iob_pdev, 0);
+
+ if (!mac->regs || !mac->dma_regs || !mac->iob_regs) {
+ dev_err(&mac->pdev->dev, "Can't map registers\n");
+ return -ENODEV;
+ }
+
+ /* The dma status structure is located in the I/O bridge, and
+ * is cache coherent.
+ */
+ if (!dma_status) {
+ dn = pci_device_to_OF_node(mac->iob_pdev);
+ if (dn)
+ err = of_address_to_resource(dn, 1, &res);
+ if (!dn || err) {
+ /* Fallback for old firmware */
+ res.start = 0xfd800000;
+ res.end = res.start + 0x1000;
+ }
+ dma_status = __ioremap(res.start, res.end-res.start, 0);
+ }
+
+ return 0;
+}
+
static int __devinit
pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
@@ -1104,21 +1161,6 @@ pasemi_mac_probe(struct pci_dev *pdev, c
mac->pdev = pdev;
mac->netdev = dev;
- mac->dma_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa007, NULL);
-
- if (!mac->dma_pdev) {
- dev_err(&pdev->dev, "Can't find DMA Controller\n");
- err = -ENODEV;
- goto out_free_netdev;
- }
-
- mac->iob_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa001, NULL);
-
- if (!mac->iob_pdev) {
- dev_err(&pdev->dev, "Can't find I/O Bridge\n");
- err = -ENODEV;
- goto out_put_dma_pdev;
- }
/* These should come out of the device tree eventually */
mac->dma_txch = index;
@@ -1161,12 +1203,9 @@ pasemi_mac_probe(struct pci_dev *pdev, c
dev->poll = pasemi_mac_poll;
dev->features = NETIF_F_HW_CSUM;
- /* The dma status structure is located in the I/O bridge, and
- * is cache coherent.
- */
- if (!dma_status)
- /* XXXOJN This should come from the device tree */
- dma_status = __ioremap(0xfd800000, 0x1000, 0);
+ err = pasemi_mac_map_regs(mac);
+ if (err)
+ goto out;
mac->rx_status = &dma_status->rx_sta[mac->dma_rxch];
mac->tx_status = &dma_status->tx_sta[mac->dma_txch];
@@ -1193,10 +1232,17 @@ pasemi_mac_probe(struct pci_dev *pdev, c
return err;
out:
- pci_dev_put(mac->iob_pdev);
-out_put_dma_pdev:
- pci_dev_put(mac->dma_pdev);
-out_free_netdev:
+ if (mac->iob_pdev)
+ pci_dev_put(mac->iob_pdev);
+ if (mac->dma_pdev)
+ pci_dev_put(mac->dma_pdev);
+ if (mac->dma_regs)
+ iounmap(mac->dma_regs);
+ if (mac->iob_regs)
+ iounmap(mac->iob_regs);
+ if (mac->regs)
+ iounmap(mac->regs);
+
free_netdev(dev);
out_disable_device:
pci_disable_device(pdev);
@@ -1220,6 +1266,10 @@ static void __devexit pasemi_mac_remove(
pci_dev_put(mac->dma_pdev);
pci_dev_put(mac->iob_pdev);
+ iounmap(mac->regs);
+ iounmap(mac->dma_regs);
+ iounmap(mac->iob_regs);
+
pci_set_drvdata(pdev, NULL);
free_netdev(netdev);
}
Index: mainline/drivers/net/pasemi_mac.h
===================================================================
--- mainline.orig/drivers/net/pasemi_mac.h
+++ mainline/drivers/net/pasemi_mac.h
@@ -52,6 +52,9 @@ struct pasemi_mac_rxring {
struct pasemi_mac {
struct net_device *netdev;
+ void __iomem *regs;
+ void __iomem *dma_regs;
+ void __iomem *iob_regs;
struct pci_dev *pdev;
struct pci_dev *dma_pdev;
struct pci_dev *iob_pdev;
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH v2] [02/10] pasemi_mac: Stop using the pci config space accessors for register read/writes
2007-08-23 18:13 ` [PATCH v2] " Olof Johansson
@ 2007-08-24 4:05 ` Stephen Rothwell
2007-08-24 18:11 ` Olof Johansson
2007-08-31 13:54 ` Jeff Garzik
1 sibling, 1 reply; 18+ messages in thread
From: Stephen Rothwell @ 2007-08-24 4:05 UTC (permalink / raw)
To: Olof Johansson; +Cc: netdev, jgarzik, linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 593 bytes --]
On Thu, 23 Aug 2007 13:13:10 -0500 Olof Johansson <olof@lixom.net> wrote:
>
> out:
> - pci_dev_put(mac->iob_pdev);
> -out_put_dma_pdev:
> - pci_dev_put(mac->dma_pdev);
> -out_free_netdev:
> + if (mac->iob_pdev)
> + pci_dev_put(mac->iob_pdev);
> + if (mac->dma_pdev)
> + pci_dev_put(mac->dma_pdev);
It is not documented as such (as far as I can see), but pci_dev_put is
safe to call with NULL. And there are other places in the kernel that
explicitly use that fact.
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2] [02/10] pasemi_mac: Stop using the pci config space accessors for register read/writes
2007-08-24 4:05 ` Stephen Rothwell
@ 2007-08-24 18:11 ` Olof Johansson
2007-08-25 1:19 ` Stephen Rothwell
0 siblings, 1 reply; 18+ messages in thread
From: Olof Johansson @ 2007-08-24 18:11 UTC (permalink / raw)
To: Stephen Rothwell; +Cc: netdev, jgarzik, linuxppc-dev
On Fri, Aug 24, 2007 at 02:05:31PM +1000, Stephen Rothwell wrote:
> On Thu, 23 Aug 2007 13:13:10 -0500 Olof Johansson <olof@lixom.net> wrote:
> >
> > out:
> > - pci_dev_put(mac->iob_pdev);
> > -out_put_dma_pdev:
> > - pci_dev_put(mac->dma_pdev);
> > -out_free_netdev:
> > + if (mac->iob_pdev)
> > + pci_dev_put(mac->iob_pdev);
> > + if (mac->dma_pdev)
> > + pci_dev_put(mac->dma_pdev);
>
> It is not documented as such (as far as I can see), but pci_dev_put is
> safe to call with NULL. And there are other places in the kernel that
> explicitly use that fact.
Some places check, others do not. I'll leave it be for now but might take
care of it during some future cleanup. Thanks for point it out though.
-Olof
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2] [02/10] pasemi_mac: Stop using the pci config space accessors for register read/writes
2007-08-24 18:11 ` Olof Johansson
@ 2007-08-25 1:19 ` Stephen Rothwell
0 siblings, 0 replies; 18+ messages in thread
From: Stephen Rothwell @ 2007-08-25 1:19 UTC (permalink / raw)
To: Olof Johansson; +Cc: netdev, jgarzik, linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 614 bytes --]
On Fri, 24 Aug 2007 13:11:04 -0500 Olof Johansson <olof@lixom.net> wrote:
>
> On Fri, Aug 24, 2007 at 02:05:31PM +1000, Stephen Rothwell wrote:
> >
> > It is not documented as such (as far as I can see), but pci_dev_put is
> > safe to call with NULL. And there are other places in the kernel that
> > explicitly use that fact.
>
> Some places check, others do not. I'll leave it be for now but might take
> care of it during some future cleanup. Thanks for point it out though.
No worries.
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2] [02/10] pasemi_mac: Stop using the pci config space accessors for register read/writes
2007-08-23 18:13 ` [PATCH v2] " Olof Johansson
2007-08-24 4:05 ` Stephen Rothwell
@ 2007-08-31 13:54 ` Jeff Garzik
1 sibling, 0 replies; 18+ messages in thread
From: Jeff Garzik @ 2007-08-31 13:54 UTC (permalink / raw)
To: Olof Johansson; +Cc: netdev, linuxppc-dev
Olof Johansson wrote:
> Move away from using the pci config access functions for simple register
> access. Our device has all of the registers in the config space (hey,
> from the hardware point of view it looks reasonable :-), so we need to
> somehow get to it. Newer firmwares have it in the device tree such that
> we can just get it and ioremap it there (in case it ever moves in future
> products). For now, provide a hardcoded fallback for older firmwares.
>
>
> Signed-off-by: Olof Johansson <olof@lixom.net>
applied 2-10
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH] [03/10] pasemi_mac: Enable L2 caching of packet headers
[not found] <20070817205413.548020000@lixom.net>
2007-08-22 14:12 ` [PATCH] [01/10] pasemi_mac: Abstract out register access Olof Johansson
2007-08-22 14:12 ` [PATCH] [02/10] pasemi_mac: Stop using the pci config space accessors for register read/writes Olof Johansson
@ 2007-08-22 14:12 ` Olof Johansson
2007-08-22 14:12 ` [PATCH] [04/10] pasemi_mac: Fix memcpy amount for short receives Olof Johansson
` (6 subsequent siblings)
9 siblings, 0 replies; 18+ messages in thread
From: Olof Johansson @ 2007-08-22 14:12 UTC (permalink / raw)
To: jgarzik; +Cc: netdev, linuxppc-dev
Enable settings to target l2 for the first few cachelines of the packet, since
we'll access them to get to the various headers.
Signed-off-by: Olof Johansson <olof@lixom.net>
Index: mainline/drivers/net/pasemi_mac.c
===================================================================
--- mainline.orig/drivers/net/pasemi_mac.c
+++ mainline/drivers/net/pasemi_mac.c
@@ -216,7 +216,7 @@ static int pasemi_mac_setup_rx_resources
PAS_DMA_RXCHAN_BASEU_SIZ(RX_RING_SIZE >> 2));
write_dma_reg(mac, PAS_DMA_RXCHAN_CFG(chan_id),
- PAS_DMA_RXCHAN_CFG_HBU(1));
+ PAS_DMA_RXCHAN_CFG_HBU(2));
write_dma_reg(mac, PAS_DMA_RXINT_BASEL(mac->dma_if),
PAS_DMA_RXINT_BASEL_BRBL(__pa(ring->buffers)));
@@ -225,6 +225,9 @@ static int pasemi_mac_setup_rx_resources
PAS_DMA_RXINT_BASEU_BRBH(__pa(ring->buffers) >> 32) |
PAS_DMA_RXINT_BASEU_SIZ(RX_RING_SIZE >> 3));
+ write_dma_reg(mac, PAS_DMA_RXINT_CFG(mac->dma_if),
+ PAS_DMA_RXINT_CFG_DHL(2));
+
ring->next_to_fill = 0;
ring->next_to_clean = 0;
Index: mainline/drivers/net/pasemi_mac.h
===================================================================
--- mainline.orig/drivers/net/pasemi_mac.h
+++ mainline/drivers/net/pasemi_mac.h
@@ -218,6 +218,14 @@ enum {
#define PAS_DMA_RXINT_RCMDSTA_ACT 0x00010000
#define PAS_DMA_RXINT_RCMDSTA_DROPS_M 0xfffe0000
#define PAS_DMA_RXINT_RCMDSTA_DROPS_S 17
+#define PAS_DMA_RXINT_CFG(i) (0x204+(i)*_PAS_DMA_RXINT_STRIDE)
+#define PAS_DMA_RXINT_CFG_DHL_M 0x07000000
+#define PAS_DMA_RXINT_CFG_DHL_S 24
+#define PAS_DMA_RXINT_CFG_DHL(x) (((x) << PAS_DMA_RXINT_CFG_DHL_S) & \
+ PAS_DMA_RXINT_CFG_DHL_M)
+#define PAS_DMA_RXINT_CFG_WIF 0x00000002
+#define PAS_DMA_RXINT_CFG_WIL 0x00000001
+
#define PAS_DMA_RXINT_INCR(i) (0x210+(i)*_PAS_DMA_RXINT_STRIDE)
#define PAS_DMA_RXINT_INCR_INCR_M 0x0000ffff
#define PAS_DMA_RXINT_INCR_INCR_S 0
--
^ permalink raw reply [flat|nested] 18+ messages in thread* [PATCH] [04/10] pasemi_mac: Fix memcpy amount for short receives
[not found] <20070817205413.548020000@lixom.net>
` (2 preceding siblings ...)
2007-08-22 14:12 ` [PATCH] [03/10] pasemi_mac: Enable L2 caching of packet headers Olof Johansson
@ 2007-08-22 14:12 ` Olof Johansson
2007-08-22 14:12 ` [PATCH] [05/10] pasemi_mac: RX performance tweaks Olof Johansson
` (5 subsequent siblings)
9 siblings, 0 replies; 18+ messages in thread
From: Olof Johansson @ 2007-08-22 14:12 UTC (permalink / raw)
To: jgarzik; +Cc: netdev, linuxppc-dev
Fix up memcpy for short receives.
Signed-off-by: Olof Johansson <olof@lixom.net>
Index: mainline/drivers/net/pasemi_mac.c
===================================================================
--- mainline.orig/drivers/net/pasemi_mac.c
+++ mainline/drivers/net/pasemi_mac.c
@@ -516,9 +516,7 @@ static int pasemi_mac_clean_rx(struct pa
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);
+ memcpy(new_skb->data, skb->data, len);
/* save the skb in buffer_info as good */
skb = new_skb;
}
--
^ permalink raw reply [flat|nested] 18+ messages in thread* [PATCH] [05/10] pasemi_mac: RX performance tweaks
[not found] <20070817205413.548020000@lixom.net>
` (3 preceding siblings ...)
2007-08-22 14:12 ` [PATCH] [04/10] pasemi_mac: Fix memcpy amount for short receives Olof Johansson
@ 2007-08-22 14:12 ` Olof Johansson
2007-08-22 14:13 ` [PATCH] [06/10] pasemi_mac: Batch up TX buffer frees Olof Johansson
` (4 subsequent siblings)
9 siblings, 0 replies; 18+ messages in thread
From: Olof Johansson @ 2007-08-22 14:12 UTC (permalink / raw)
To: jgarzik; +Cc: netdev, linuxppc-dev
Various RX performance tweaks, do some explicit prefetching of packet
data, etc.
Signed-off-by: Olof Johansson <olof@lixom.net>
Index: mainline/drivers/net/pasemi_mac.c
===================================================================
--- mainline.orig/drivers/net/pasemi_mac.c
+++ mainline/drivers/net/pasemi_mac.c
@@ -481,6 +481,7 @@ static int pasemi_mac_clean_rx(struct pa
rmb();
dp = &RX_DESC(mac, n);
+ prefetchw(dp);
macrx = dp->macrx;
if (!(macrx & XCT_MACRX_O))
@@ -502,8 +503,10 @@ static int pasemi_mac_clean_rx(struct pa
if (info->dma == dma)
break;
}
+ prefetchw(info);
skb = info->skb;
+ prefetchw(skb);
info->dma = 0;
pci_unmap_single(mac->dma_pdev, dma, skb->len,
@@ -526,9 +529,7 @@ static int pasemi_mac_clean_rx(struct pa
skb_put(skb, len);
- skb->protocol = eth_type_trans(skb, mac->netdev);
-
- if ((macrx & XCT_MACRX_HTY_M) == XCT_MACRX_HTY_IPV4_OK) {
+ if (likely((macrx & XCT_MACRX_HTY_M) == XCT_MACRX_HTY_IPV4_OK)) {
skb->ip_summed = CHECKSUM_COMPLETE;
skb->csum = (macrx & XCT_MACRX_CSUM_M) >>
XCT_MACRX_CSUM_S;
@@ -538,6 +539,7 @@ static int pasemi_mac_clean_rx(struct pa
mac->stats.rx_bytes += len;
mac->stats.rx_packets++;
+ skb->protocol = eth_type_trans(skb, mac->netdev);
netif_receive_skb(skb);
dp->ptr = 0;
@@ -569,7 +571,7 @@ static int pasemi_mac_clean_tx(struct pa
for (i = start; i < mac->tx->next_to_use; i++) {
dp = &TX_DESC(mac, i);
- if (!dp || (dp->mactx & XCT_MACTX_O))
+ if (unlikely(dp->mactx & XCT_MACTX_O))
break;
count++;
@@ -957,7 +959,7 @@ static int pasemi_mac_start_tx(struct sk
struct pasemi_mac_txring *txring;
struct pasemi_mac_buffer *info;
struct pas_dma_xct_descr *dp;
- u64 dflags;
+ u64 dflags, mactx, ptr;
dma_addr_t map;
int flags;
@@ -985,6 +987,9 @@ static int pasemi_mac_start_tx(struct sk
if (dma_mapping_error(map))
return NETDEV_TX_BUSY;
+ mactx = dflags | XCT_MACTX_LLEN(skb->len);
+ ptr = XCT_PTR_LEN(skb->len) | XCT_PTR_ADDR(map);
+
txring = mac->tx;
spin_lock_irqsave(&txring->lock, flags);
@@ -1005,12 +1010,11 @@ static int pasemi_mac_start_tx(struct sk
}
}
-
dp = &TX_DESC(mac, txring->next_to_use);
info = &TX_DESC_INFO(mac, txring->next_to_use);
- dp->mactx = dflags | XCT_MACTX_LLEN(skb->len);
- dp->ptr = XCT_PTR_LEN(skb->len) | XCT_PTR_ADDR(map);
+ dp->mactx = mactx;
+ dp->ptr = ptr;
info->dma = map;
info->skb = skb;
--
^ permalink raw reply [flat|nested] 18+ messages in thread* [PATCH] [06/10] pasemi_mac: Batch up TX buffer frees
[not found] <20070817205413.548020000@lixom.net>
` (4 preceding siblings ...)
2007-08-22 14:12 ` [PATCH] [05/10] pasemi_mac: RX performance tweaks Olof Johansson
@ 2007-08-22 14:13 ` Olof Johansson
2007-08-22 14:13 ` [PATCH] [07/10] pasemi_mac: Enable LLTX Olof Johansson
` (3 subsequent siblings)
9 siblings, 0 replies; 18+ messages in thread
From: Olof Johansson @ 2007-08-22 14:13 UTC (permalink / raw)
To: jgarzik; +Cc: netdev, linuxppc-dev
Postpone pci unmap and skb free of the transmitted buffers to outside of
the tx ring lock, batching them up 32 at a time.
Also increase the count threshold to 128.
Signed-off-by: Olof Johansson <olof@lixom.net>
Index: mainline/drivers/net/pasemi_mac.c
===================================================================
--- mainline.orig/drivers/net/pasemi_mac.c
+++ mainline/drivers/net/pasemi_mac.c
@@ -561,37 +561,56 @@ static int pasemi_mac_clean_tx(struct pa
int i;
struct pasemi_mac_buffer *info;
struct pas_dma_xct_descr *dp;
- int start, count;
+ unsigned int start, count, limit;
+ unsigned int total_count;
int flags;
+ struct sk_buff *skbs[32];
+ dma_addr_t dmas[32];
+ total_count = 0;
+restart:
spin_lock_irqsave(&mac->tx->lock, flags);
start = mac->tx->next_to_clean;
+ limit = min(mac->tx->next_to_use, start+32);
+
count = 0;
- for (i = start; i < mac->tx->next_to_use; i++) {
+ for (i = start; i < limit; i++) {
dp = &TX_DESC(mac, i);
+
if (unlikely(dp->mactx & XCT_MACTX_O))
+ /* Not yet transmitted */
break;
- count++;
-
info = &TX_DESC_INFO(mac, i);
-
- pci_unmap_single(mac->dma_pdev, info->dma,
- info->skb->len, PCI_DMA_TODEVICE);
- dev_kfree_skb_irq(info->skb);
+ skbs[count] = info->skb;
+ dmas[count] = info->dma;
info->skb = NULL;
info->dma = 0;
dp->mactx = 0;
dp->ptr = 0;
+
+ count++;
}
mac->tx->next_to_clean += count;
spin_unlock_irqrestore(&mac->tx->lock, flags);
netif_wake_queue(mac->netdev);
- return count;
+ for (i = 0; i < count; i++) {
+ pci_unmap_single(mac->dma_pdev, dmas[i],
+ skbs[i]->len, PCI_DMA_TODEVICE);
+ dev_kfree_skb_irq(skbs[i]);
+ }
+
+ total_count += count;
+
+ /* If the batch was full, try to clean more */
+ if (count == 32)
+ goto restart;
+
+ return total_count;
}
@@ -787,7 +806,7 @@ static int pasemi_mac_open(struct net_de
PAS_IOB_DMA_RXCH_CFG_CNTTH(0));
write_iob_reg(mac, PAS_IOB_DMA_TXCH_CFG(mac->dma_txch),
- PAS_IOB_DMA_TXCH_CFG_CNTTH(32));
+ PAS_IOB_DMA_TXCH_CFG_CNTTH(128));
/* Clear out any residual packet count state from firmware */
pasemi_mac_restart_rx_intr(mac);
--
^ permalink raw reply [flat|nested] 18+ messages in thread* [PATCH] [07/10] pasemi_mac: Enable LLTX
[not found] <20070817205413.548020000@lixom.net>
` (5 preceding siblings ...)
2007-08-22 14:13 ` [PATCH] [06/10] pasemi_mac: Batch up TX buffer frees Olof Johansson
@ 2007-08-22 14:13 ` Olof Johansson
2007-08-22 14:13 ` [PATCH] [08/10] pasemi_mac: Fix TX ring wrap checking Olof Johansson
` (2 subsequent siblings)
9 siblings, 0 replies; 18+ messages in thread
From: Olof Johansson @ 2007-08-22 14:13 UTC (permalink / raw)
To: jgarzik; +Cc: netdev, linuxppc-dev
Enable LLTX on pasemi_mac: we're already doing sufficient locking
in the driver to enable it.
Signed-off-by: Olof Johansson <olof@lixom.net>
Index: mainline/drivers/net/pasemi_mac.c
===================================================================
--- mainline.orig/drivers/net/pasemi_mac.c
+++ mainline/drivers/net/pasemi_mac.c
@@ -1235,7 +1235,7 @@ pasemi_mac_probe(struct pci_dev *pdev, c
dev->set_multicast_list = pasemi_mac_set_rx_mode;
dev->weight = 64;
dev->poll = pasemi_mac_poll;
- dev->features = NETIF_F_HW_CSUM;
+ dev->features = NETIF_F_HW_CSUM | NETIF_F_LLTX;
err = pasemi_mac_map_regs(mac);
if (err)
--
^ permalink raw reply [flat|nested] 18+ messages in thread* [PATCH] [08/10] pasemi_mac: Fix TX ring wrap checking
[not found] <20070817205413.548020000@lixom.net>
` (6 preceding siblings ...)
2007-08-22 14:13 ` [PATCH] [07/10] pasemi_mac: Enable LLTX Olof Johansson
@ 2007-08-22 14:13 ` Olof Johansson
2007-08-22 14:13 ` [PATCH] [09/10] pasemi_mac: Fix RX checksum flags Olof Johansson
2007-08-22 14:13 ` [PATCH] [10/10] pasemi_mac: Clean TX ring in poll Olof Johansson
9 siblings, 0 replies; 18+ messages in thread
From: Olof Johansson @ 2007-08-22 14:13 UTC (permalink / raw)
To: jgarzik; +Cc: netdev, linuxppc-dev
The old logic didn't detect full (tx) ring cases properly, causing
overruns and general badness. Clean it up a bit and abstract out the
ring size checks, always making sure to leave 1 slot open.
Signed-off-by: Olof Johansson <olof@lixom.net>
Index: mainline/drivers/net/pasemi_mac.c
===================================================================
--- mainline.orig/drivers/net/pasemi_mac.c
+++ mainline/drivers/net/pasemi_mac.c
@@ -69,6 +69,10 @@
#define RX_DESC_INFO(mac, num) ((mac)->rx->desc_info[(num) & (RX_RING_SIZE-1)])
#define RX_BUFF(mac, num) ((mac)->rx->buffers[(num) & (RX_RING_SIZE-1)])
+#define RING_USED(ring) (((ring)->next_to_fill - (ring)->next_to_clean) \
+ & ((ring)->size - 1))
+#define RING_AVAIL(ring) ((ring->size) - RING_USED(ring))
+
#define BUF_SIZE 1646 /* 1500 MTU + ETH_HLEN + VLAN_HLEN + 2 64B cachelines */
MODULE_LICENSE("GPL");
@@ -184,6 +188,7 @@ static int pasemi_mac_setup_rx_resources
spin_lock_init(&ring->lock);
+ ring->size = RX_RING_SIZE;
ring->desc_info = kzalloc(sizeof(struct pasemi_mac_buffer) *
RX_RING_SIZE, GFP_KERNEL);
@@ -263,6 +268,7 @@ static int pasemi_mac_setup_tx_resources
spin_lock_init(&ring->lock);
+ ring->size = TX_RING_SIZE;
ring->desc_info = kzalloc(sizeof(struct pasemi_mac_buffer) *
TX_RING_SIZE, GFP_KERNEL);
if (!ring->desc_info)
@@ -291,7 +297,7 @@ static int pasemi_mac_setup_tx_resources
PAS_DMA_TXCHAN_CFG_UP |
PAS_DMA_TXCHAN_CFG_WT(2));
- ring->next_to_use = 0;
+ ring->next_to_fill = 0;
ring->next_to_clean = 0;
snprintf(ring->irq_name, sizeof(ring->irq_name),
@@ -386,9 +392,7 @@ static void pasemi_mac_replenish_rx_ring
int start = mac->rx->next_to_fill;
unsigned int limit, count;
- limit = (mac->rx->next_to_clean + RX_RING_SIZE -
- mac->rx->next_to_fill) & (RX_RING_SIZE - 1);
-
+ limit = RING_AVAIL(mac->rx);
/* Check to see if we're doing first-time setup */
if (unlikely(mac->rx->next_to_clean == 0 && mac->rx->next_to_fill == 0))
limit = RX_RING_SIZE;
@@ -572,7 +576,7 @@ restart:
spin_lock_irqsave(&mac->tx->lock, flags);
start = mac->tx->next_to_clean;
- limit = min(mac->tx->next_to_use, start+32);
+ limit = min(mac->tx->next_to_fill, start+32);
count = 0;
@@ -1013,14 +1017,13 @@ static int pasemi_mac_start_tx(struct sk
spin_lock_irqsave(&txring->lock, flags);
- if (txring->next_to_clean - txring->next_to_use == TX_RING_SIZE) {
+ if (RING_AVAIL(txring) <= 1) {
spin_unlock_irqrestore(&txring->lock, flags);
pasemi_mac_clean_tx(mac);
pasemi_mac_restart_tx_intr(mac);
spin_lock_irqsave(&txring->lock, flags);
- if (txring->next_to_clean - txring->next_to_use ==
- TX_RING_SIZE) {
+ if (RING_AVAIL(txring) <= 1) {
/* Still no room -- stop the queue and wait for tx
* intr when there's room.
*/
@@ -1029,15 +1032,15 @@ static int pasemi_mac_start_tx(struct sk
}
}
- dp = &TX_DESC(mac, txring->next_to_use);
- info = &TX_DESC_INFO(mac, txring->next_to_use);
+ dp = &TX_DESC(mac, txring->next_to_fill);
+ info = &TX_DESC_INFO(mac, txring->next_to_fill);
dp->mactx = mactx;
dp->ptr = ptr;
info->dma = map;
info->skb = skb;
- txring->next_to_use++;
+ txring->next_to_fill++;
mac->stats.tx_packets++;
mac->stats.tx_bytes += skb->len;
Index: mainline/drivers/net/pasemi_mac.h
===================================================================
--- mainline.orig/drivers/net/pasemi_mac.h
+++ mainline/drivers/net/pasemi_mac.h
@@ -31,7 +31,7 @@ struct pasemi_mac_txring {
struct pas_dma_xct_descr *desc;
dma_addr_t dma;
unsigned int size;
- unsigned int next_to_use;
+ unsigned int next_to_fill;
unsigned int next_to_clean;
struct pasemi_mac_buffer *desc_info;
char irq_name[10]; /* "eth%d tx" */
--
^ permalink raw reply [flat|nested] 18+ messages in thread* [PATCH] [09/10] pasemi_mac: Fix RX checksum flags
[not found] <20070817205413.548020000@lixom.net>
` (7 preceding siblings ...)
2007-08-22 14:13 ` [PATCH] [08/10] pasemi_mac: Fix TX ring wrap checking Olof Johansson
@ 2007-08-22 14:13 ` Olof Johansson
2007-08-22 14:13 ` [PATCH] [10/10] pasemi_mac: Clean TX ring in poll Olof Johansson
9 siblings, 0 replies; 18+ messages in thread
From: Olof Johansson @ 2007-08-22 14:13 UTC (permalink / raw)
To: jgarzik; +Cc: netdev, linuxppc-dev
RX side flag to use is CHECKSUM_UNNECESSARY, not CHECKSUM_COMPLETE.
Signed-off-by: Olof Johansson <olof@lixom.net>
Index: mainline/drivers/net/pasemi_mac.c
===================================================================
--- mainline.orig/drivers/net/pasemi_mac.c
+++ mainline/drivers/net/pasemi_mac.c
@@ -534,7 +534,7 @@ static int pasemi_mac_clean_rx(struct pa
skb_put(skb, len);
if (likely((macrx & XCT_MACRX_HTY_M) == XCT_MACRX_HTY_IPV4_OK)) {
- skb->ip_summed = CHECKSUM_COMPLETE;
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
skb->csum = (macrx & XCT_MACRX_CSUM_M) >>
XCT_MACRX_CSUM_S;
} else
--
^ permalink raw reply [flat|nested] 18+ messages in thread* [PATCH] [10/10] pasemi_mac: Clean TX ring in poll
[not found] <20070817205413.548020000@lixom.net>
` (8 preceding siblings ...)
2007-08-22 14:13 ` [PATCH] [09/10] pasemi_mac: Fix RX checksum flags Olof Johansson
@ 2007-08-22 14:13 ` Olof Johansson
9 siblings, 0 replies; 18+ messages in thread
From: Olof Johansson @ 2007-08-22 14:13 UTC (permalink / raw)
To: jgarzik; +Cc: netdev, linuxppc-dev
Unfortunately there's no timeout for how long a packet can sit on
the TX ring after completion before an interrupt is generated, and
we want to have a threshold that's larger than one packet per interrupt.
So we have to have a timer that occasionally cleans the TX ring even
though there hasn't been an interrupt. Instead of setting up a dedicated
timer for this, just clean it in the NAPI poll routine instead.
Signed-off-by: Olof Johansson <olof@lixom.net>
---
I know I got this rejected last time it was submitted, but no answers with
suggestions on how to handle it better. I'm all ears if there's a better
way. (I noticed that Intel's new ixgbe driver does the same thing).
Index: mainline/drivers/net/pasemi_mac.c
===================================================================
--- mainline.orig/drivers/net/pasemi_mac.c
+++ mainline/drivers/net/pasemi_mac.c
@@ -1086,6 +1086,7 @@ static int pasemi_mac_poll(struct net_de
int pkts, limit = min(*budget, dev->quota);
struct pasemi_mac *mac = netdev_priv(dev);
+ pasemi_mac_clean_tx(mac);
pkts = pasemi_mac_clean_rx(mac, limit);
dev->quota -= pkts;
--
^ permalink raw reply [flat|nested] 18+ messages in thread