aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorRon Mercer <ron.mercer@qlogic.com>2009-01-09 06:31:49 -0500
committerDavid S. Miller <davem@davemloft.net>2009-01-11 03:07:34 -0500
commitba7cd3ba97f81564be3e4a4ee8ee17726aa853d7 (patch)
tree30640bced4bf5bf4642e4cfe6a9146a0173bde5d /drivers
parentf1405d32e392f2f5f80f4687fe186305de300bf6 (diff)
qlge: Get rid of volatile usage for shadow register.
Putting back ql_read_sh_reg() function and using rmb() instead of volatile. Signed-off-by: Ron Mercer <ron.mercer@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/qlge/qlge.h22
-rw-r--r--drivers/net/qlge/qlge_dbg.c14
-rw-r--r--drivers/net/qlge/qlge_main.c12
3 files changed, 34 insertions, 14 deletions
diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h
index 459663a4023d..4cb3647bb1b0 100644
--- a/drivers/net/qlge/qlge.h
+++ b/drivers/net/qlge/qlge.h
@@ -1145,7 +1145,7 @@ struct tx_ring {
1145 struct wqicb wqicb; /* structure used to inform chip of new queue */ 1145 struct wqicb wqicb; /* structure used to inform chip of new queue */
1146 void *wq_base; /* pci_alloc:virtual addr for tx */ 1146 void *wq_base; /* pci_alloc:virtual addr for tx */
1147 dma_addr_t wq_base_dma; /* pci_alloc:dma addr for tx */ 1147 dma_addr_t wq_base_dma; /* pci_alloc:dma addr for tx */
1148 u32 *cnsmr_idx_sh_reg; /* shadow copy of consumer idx */ 1148 __le32 *cnsmr_idx_sh_reg; /* shadow copy of consumer idx */
1149 dma_addr_t cnsmr_idx_sh_reg_dma; /* dma-shadow copy of consumer */ 1149 dma_addr_t cnsmr_idx_sh_reg_dma; /* dma-shadow copy of consumer */
1150 u32 wq_size; /* size in bytes of queue area */ 1150 u32 wq_size; /* size in bytes of queue area */
1151 u32 wq_len; /* number of entries in queue */ 1151 u32 wq_len; /* number of entries in queue */
@@ -1181,7 +1181,7 @@ struct rx_ring {
1181 u32 cq_size; 1181 u32 cq_size;
1182 u32 cq_len; 1182 u32 cq_len;
1183 u16 cq_id; 1183 u16 cq_id;
1184 volatile __le32 *prod_idx_sh_reg; /* Shadowed producer register. */ 1184 __le32 *prod_idx_sh_reg; /* Shadowed producer register. */
1185 dma_addr_t prod_idx_sh_reg_dma; 1185 dma_addr_t prod_idx_sh_reg_dma;
1186 void __iomem *cnsmr_idx_db_reg; /* PCI doorbell mem area + 0 */ 1186 void __iomem *cnsmr_idx_db_reg; /* PCI doorbell mem area + 0 */
1187 u32 cnsmr_idx; /* current sw idx */ 1187 u32 cnsmr_idx; /* current sw idx */
@@ -1459,6 +1459,24 @@ static inline void ql_write_db_reg(u32 val, void __iomem *addr)
1459 mmiowb(); 1459 mmiowb();
1460} 1460}
1461 1461
1462/*
1463 * Shadow Registers:
1464 * Outbound queues have a consumer index that is maintained by the chip.
1465 * Inbound queues have a producer index that is maintained by the chip.
1466 * For lower overhead, these registers are "shadowed" to host memory
1467 * which allows the device driver to track the queue progress without
1468 * PCI reads. When an entry is placed on an inbound queue, the chip will
1469 * update the relevant index register and then copy the value to the
1470 * shadow register in host memory.
1471 */
1472static inline u32 ql_read_sh_reg(__le32 *addr)
1473{
1474 u32 reg;
1475 reg = le32_to_cpu(*addr);
1476 rmb();
1477 return reg;
1478}
1479
1462extern char qlge_driver_name[]; 1480extern char qlge_driver_name[];
1463extern const char qlge_driver_version[]; 1481extern const char qlge_driver_version[];
1464extern const struct ethtool_ops qlge_ethtool_ops; 1482extern const struct ethtool_ops qlge_ethtool_ops;
diff --git a/drivers/net/qlge/qlge_dbg.c b/drivers/net/qlge/qlge_dbg.c
index 3f5e02d2e4a9..e705ea5b975a 100644
--- a/drivers/net/qlge/qlge_dbg.c
+++ b/drivers/net/qlge/qlge_dbg.c
@@ -455,10 +455,11 @@ void ql_dump_tx_ring(struct tx_ring *tx_ring)
455 printk(KERN_ERR PFX "tx_ring->base = %p.\n", tx_ring->wq_base); 455 printk(KERN_ERR PFX "tx_ring->base = %p.\n", tx_ring->wq_base);
456 printk(KERN_ERR PFX "tx_ring->base_dma = 0x%llx.\n", 456 printk(KERN_ERR PFX "tx_ring->base_dma = 0x%llx.\n",
457 (unsigned long long) tx_ring->wq_base_dma); 457 (unsigned long long) tx_ring->wq_base_dma);
458 printk(KERN_ERR PFX "tx_ring->cnsmr_idx_sh_reg = %p.\n", 458 printk(KERN_ERR PFX
459 tx_ring->cnsmr_idx_sh_reg); 459 "tx_ring->cnsmr_idx_sh_reg, addr = 0x%p, value = %d.\n",
460 printk(KERN_ERR PFX "tx_ring->cnsmr_idx_sh_reg_dma = 0x%llx.\n", 460 tx_ring->cnsmr_idx_sh_reg,
461 (unsigned long long) tx_ring->cnsmr_idx_sh_reg_dma); 461 tx_ring->cnsmr_idx_sh_reg
462 ? ql_read_sh_reg(tx_ring->cnsmr_idx_sh_reg) : 0);
462 printk(KERN_ERR PFX "tx_ring->size = %d.\n", tx_ring->wq_size); 463 printk(KERN_ERR PFX "tx_ring->size = %d.\n", tx_ring->wq_size);
463 printk(KERN_ERR PFX "tx_ring->len = %d.\n", tx_ring->wq_len); 464 printk(KERN_ERR PFX "tx_ring->len = %d.\n", tx_ring->wq_len);
464 printk(KERN_ERR PFX "tx_ring->prod_idx_db_reg = %p.\n", 465 printk(KERN_ERR PFX "tx_ring->prod_idx_db_reg = %p.\n",
@@ -558,9 +559,10 @@ void ql_dump_rx_ring(struct rx_ring *rx_ring)
558 printk(KERN_ERR PFX "rx_ring->cq_size = %d.\n", rx_ring->cq_size); 559 printk(KERN_ERR PFX "rx_ring->cq_size = %d.\n", rx_ring->cq_size);
559 printk(KERN_ERR PFX "rx_ring->cq_len = %d.\n", rx_ring->cq_len); 560 printk(KERN_ERR PFX "rx_ring->cq_len = %d.\n", rx_ring->cq_len);
560 printk(KERN_ERR PFX 561 printk(KERN_ERR PFX
561 "rx_ring->prod_idx_sh_reg, addr = %p, value = %d.\n", 562 "rx_ring->prod_idx_sh_reg, addr = 0x%p, value = %d.\n",
562 rx_ring->prod_idx_sh_reg, 563 rx_ring->prod_idx_sh_reg,
563 rx_ring->prod_idx_sh_reg ? *(rx_ring->prod_idx_sh_reg) : 0); 564 rx_ring->prod_idx_sh_reg
565 ? ql_read_sh_reg(rx_ring->prod_idx_sh_reg) : 0);
564 printk(KERN_ERR PFX "rx_ring->prod_idx_sh_reg_dma = %llx.\n", 566 printk(KERN_ERR PFX "rx_ring->prod_idx_sh_reg_dma = %llx.\n",
565 (unsigned long long) rx_ring->prod_idx_sh_reg_dma); 567 (unsigned long long) rx_ring->prod_idx_sh_reg_dma);
566 printk(KERN_ERR PFX "rx_ring->cnsmr_idx_db_reg = %p.\n", 568 printk(KERN_ERR PFX "rx_ring->cnsmr_idx_db_reg = %p.\n",
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index b7e40add9586..78df7d11cef1 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -1545,7 +1545,7 @@ static void ql_process_chip_ae_intr(struct ql_adapter *qdev,
1545static int ql_clean_outbound_rx_ring(struct rx_ring *rx_ring) 1545static int ql_clean_outbound_rx_ring(struct rx_ring *rx_ring)
1546{ 1546{
1547 struct ql_adapter *qdev = rx_ring->qdev; 1547 struct ql_adapter *qdev = rx_ring->qdev;
1548 u32 prod = le32_to_cpu(*rx_ring->prod_idx_sh_reg); 1548 u32 prod = ql_read_sh_reg(rx_ring->prod_idx_sh_reg);
1549 struct ob_mac_iocb_rsp *net_rsp = NULL; 1549 struct ob_mac_iocb_rsp *net_rsp = NULL;
1550 int count = 0; 1550 int count = 0;
1551 1551
@@ -1571,7 +1571,7 @@ static int ql_clean_outbound_rx_ring(struct rx_ring *rx_ring)
1571 } 1571 }
1572 count++; 1572 count++;
1573 ql_update_cq(rx_ring); 1573 ql_update_cq(rx_ring);
1574 prod = le32_to_cpu(*rx_ring->prod_idx_sh_reg); 1574 prod = ql_read_sh_reg(rx_ring->prod_idx_sh_reg);
1575 } 1575 }
1576 ql_write_cq_idx(rx_ring); 1576 ql_write_cq_idx(rx_ring);
1577 if (netif_queue_stopped(qdev->ndev) && net_rsp != NULL) { 1577 if (netif_queue_stopped(qdev->ndev) && net_rsp != NULL) {
@@ -1591,7 +1591,7 @@ static int ql_clean_outbound_rx_ring(struct rx_ring *rx_ring)
1591static int ql_clean_inbound_rx_ring(struct rx_ring *rx_ring, int budget) 1591static int ql_clean_inbound_rx_ring(struct rx_ring *rx_ring, int budget)
1592{ 1592{
1593 struct ql_adapter *qdev = rx_ring->qdev; 1593 struct ql_adapter *qdev = rx_ring->qdev;
1594 u32 prod = le32_to_cpu(*rx_ring->prod_idx_sh_reg); 1594 u32 prod = ql_read_sh_reg(rx_ring->prod_idx_sh_reg);
1595 struct ql_net_rsp_iocb *net_rsp; 1595 struct ql_net_rsp_iocb *net_rsp;
1596 int count = 0; 1596 int count = 0;
1597 1597
@@ -1624,7 +1624,7 @@ static int ql_clean_inbound_rx_ring(struct rx_ring *rx_ring, int budget)
1624 } 1624 }
1625 count++; 1625 count++;
1626 ql_update_cq(rx_ring); 1626 ql_update_cq(rx_ring);
1627 prod = le32_to_cpu(*rx_ring->prod_idx_sh_reg); 1627 prod = ql_read_sh_reg(rx_ring->prod_idx_sh_reg);
1628 if (count == budget) 1628 if (count == budget)
1629 break; 1629 break;
1630 } 1630 }
@@ -1787,7 +1787,7 @@ static irqreturn_t qlge_isr(int irq, void *dev_id)
1787 * Check the default queue and wake handler if active. 1787 * Check the default queue and wake handler if active.
1788 */ 1788 */
1789 rx_ring = &qdev->rx_ring[0]; 1789 rx_ring = &qdev->rx_ring[0];
1790 if (le32_to_cpu(*rx_ring->prod_idx_sh_reg) != rx_ring->cnsmr_idx) { 1790 if (ql_read_sh_reg(rx_ring->prod_idx_sh_reg) != rx_ring->cnsmr_idx) {
1791 QPRINTK(qdev, INTR, INFO, "Waking handler for rx_ring[0].\n"); 1791 QPRINTK(qdev, INTR, INFO, "Waking handler for rx_ring[0].\n");
1792 ql_disable_completion_interrupt(qdev, intr_context->intr); 1792 ql_disable_completion_interrupt(qdev, intr_context->intr);
1793 queue_delayed_work_on(smp_processor_id(), qdev->q_workqueue, 1793 queue_delayed_work_on(smp_processor_id(), qdev->q_workqueue,
@@ -1801,7 +1801,7 @@ static irqreturn_t qlge_isr(int irq, void *dev_id)
1801 */ 1801 */
1802 for (i = 1; i < qdev->rx_ring_count; i++) { 1802 for (i = 1; i < qdev->rx_ring_count; i++) {
1803 rx_ring = &qdev->rx_ring[i]; 1803 rx_ring = &qdev->rx_ring[i];
1804 if (le32_to_cpu(*rx_ring->prod_idx_sh_reg) != 1804 if (ql_read_sh_reg(rx_ring->prod_idx_sh_reg) !=
1805 rx_ring->cnsmr_idx) { 1805 rx_ring->cnsmr_idx) {
1806 QPRINTK(qdev, INTR, INFO, 1806 QPRINTK(qdev, INTR, INFO,
1807 "Waking handler for rx_ring[%d].\n", i); 1807 "Waking handler for rx_ring[%d].\n", i);