* [net-next PATCH 1/3] qlge: Fix indentations.
2009-11-03 23:49 [net-next PATCH 0/3] qlge: Clean up and firmware subcommands Ron Mercer
@ 2009-11-03 23:49 ` Ron Mercer
2009-11-03 23:49 ` [net-next PATCH 2/3] qlge: Add firmware/driver sub-command support Ron Mercer
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Ron Mercer @ 2009-11-03 23:49 UTC (permalink / raw)
To: davem; +Cc: netdev, ron.mercer
Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
---
drivers/net/qlge/qlge_main.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index fa53009..4a07548 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -2102,12 +2102,12 @@ static irqreturn_t qlge_isr(int irq, void *dev_id)
*/
var = ql_read32(qdev, ISR1);
if (var & intr_context->irq_mask) {
- QPRINTK(qdev, INTR, INFO,
+ QPRINTK(qdev, INTR, INFO,
"Waking handler for rx_ring[0].\n");
ql_disable_completion_interrupt(qdev, intr_context->intr);
- napi_schedule(&rx_ring->napi);
- work_done++;
- }
+ napi_schedule(&rx_ring->napi);
+ work_done++;
+ }
ql_enable_completion_interrupt(qdev, intr_context->intr);
return work_done ? IRQ_HANDLED : IRQ_NONE;
}
--
1.6.0.2
^ permalink raw reply related [flat|nested] 5+ messages in thread* [net-next PATCH 2/3] qlge: Add firmware/driver sub-command support.
2009-11-03 23:49 [net-next PATCH 0/3] qlge: Clean up and firmware subcommands Ron Mercer
2009-11-03 23:49 ` [net-next PATCH 1/3] qlge: Fix indentations Ron Mercer
@ 2009-11-03 23:49 ` Ron Mercer
2009-11-03 23:49 ` [net-next PATCH 3/3] qlge: Clean up netdev->stats usage Ron Mercer
2009-11-04 13:03 ` [net-next PATCH 0/3] qlge: Clean up and firmware subcommands David Miller
3 siblings, 0 replies; 5+ messages in thread
From: Ron Mercer @ 2009-11-03 23:49 UTC (permalink / raw)
To: davem; +Cc: netdev, ron.mercer
These sub-commands are issued by another (FCoE) function requesting
an operation on a shared resource.
Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
---
drivers/net/qlge/qlge.h | 12 +++++++++
drivers/net/qlge/qlge_mpi.c | 56 +++++++++++++++++++++++++++++++++++++-----
2 files changed, 61 insertions(+), 7 deletions(-)
diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h
index 872e95e..5e4d343 100644
--- a/drivers/net/qlge/qlge.h
+++ b/drivers/net/qlge/qlge.h
@@ -816,6 +816,18 @@ enum {
MB_CMD_GET_MGMNT_TFK_CTL = 0x00000161, /* Get Mgmnt Traffic Control */
MB_GET_MPI_TFK_STOPPED = (1 << 0),
MB_GET_MPI_TFK_FIFO_EMPTY = (1 << 1),
+ /* Sub-commands for IDC request.
+ * This describes the reason for the
+ * IDC request.
+ */
+ MB_CMD_IOP_NONE = 0x0000,
+ MB_CMD_IOP_PREP_UPDATE_MPI = 0x0001,
+ MB_CMD_IOP_COMP_UPDATE_MPI = 0x0002,
+ MB_CMD_IOP_PREP_LINK_DOWN = 0x0010,
+ MB_CMD_IOP_DVR_START = 0x0100,
+ MB_CMD_IOP_FLASH_ACC = 0x0101,
+ MB_CMD_IOP_RESTART_MPI = 0x0102,
+ MB_CMD_IOP_CORE_DUMP_MPI = 0x0103,
/* Mailbox Command Status. */
MB_CMD_STS_GOOD = 0x00004000, /* Success. */
diff --git a/drivers/net/qlge/qlge_mpi.c b/drivers/net/qlge/qlge_mpi.c
index bac7b86..f5619fe 100644
--- a/drivers/net/qlge/qlge_mpi.c
+++ b/drivers/net/qlge/qlge_mpi.c
@@ -1038,8 +1038,11 @@ void ql_mpi_idc_work(struct work_struct *work)
int status;
struct mbox_params *mbcp = &qdev->idc_mbc;
u32 aen;
+ int timeout;
+ rtnl_lock();
aen = mbcp->mbox_out[1] >> 16;
+ timeout = (mbcp->mbox_out[1] >> 8) & 0xf;
switch (aen) {
default:
@@ -1047,22 +1050,61 @@ void ql_mpi_idc_work(struct work_struct *work)
"Bug: Unhandled IDC action.\n");
break;
case MB_CMD_PORT_RESET:
- case MB_CMD_SET_PORT_CFG:
case MB_CMD_STOP_FW:
ql_link_off(qdev);
+ case MB_CMD_SET_PORT_CFG:
/* Signal the resulting link up AEN
* that the frame routing and mac addr
* needs to be set.
* */
set_bit(QL_CAM_RT_SET, &qdev->flags);
- rtnl_lock();
- status = ql_mb_idc_ack(qdev);
- rtnl_unlock();
- if (status) {
- QPRINTK(qdev, DRV, ERR,
- "Bug: No pending IDC!\n");
+ /* Do ACK if required */
+ if (timeout) {
+ status = ql_mb_idc_ack(qdev);
+ if (status)
+ QPRINTK(qdev, DRV, ERR,
+ "Bug: No pending IDC!\n");
+ } else {
+ QPRINTK(qdev, DRV, DEBUG,
+ "IDC ACK not required\n");
+ status = 0; /* success */
+ }
+ break;
+
+ /* These sub-commands issued by another (FCoE)
+ * function are requesting to do an operation
+ * on the shared resource (MPI environment).
+ * We currently don't issue these so we just
+ * ACK the request.
+ */
+ case MB_CMD_IOP_RESTART_MPI:
+ case MB_CMD_IOP_PREP_LINK_DOWN:
+ /* Drop the link, reload the routing
+ * table when link comes up.
+ */
+ ql_link_off(qdev);
+ set_bit(QL_CAM_RT_SET, &qdev->flags);
+ /* Fall through. */
+ case MB_CMD_IOP_DVR_START:
+ case MB_CMD_IOP_FLASH_ACC:
+ case MB_CMD_IOP_CORE_DUMP_MPI:
+ case MB_CMD_IOP_PREP_UPDATE_MPI:
+ case MB_CMD_IOP_COMP_UPDATE_MPI:
+ case MB_CMD_IOP_NONE: /* an IDC without params */
+ /* Do ACK if required */
+ if (timeout) {
+ status = ql_mb_idc_ack(qdev);
+ if (status)
+ QPRINTK(qdev, DRV, ERR,
+ "Bug: No pending IDC!\n");
+ } else {
+ QPRINTK(qdev, DRV, DEBUG,
+ "IDC ACK not required\n");
+ status = 0; /* success */
}
+ break;
}
+ rtnl_unlock();
}
void ql_mpi_work(struct work_struct *work)
--
1.6.0.2
^ permalink raw reply related [flat|nested] 5+ messages in thread* [net-next PATCH 3/3] qlge: Clean up netdev->stats usage.
2009-11-03 23:49 [net-next PATCH 0/3] qlge: Clean up and firmware subcommands Ron Mercer
2009-11-03 23:49 ` [net-next PATCH 1/3] qlge: Fix indentations Ron Mercer
2009-11-03 23:49 ` [net-next PATCH 2/3] qlge: Add firmware/driver sub-command support Ron Mercer
@ 2009-11-03 23:49 ` Ron Mercer
2009-11-04 13:03 ` [net-next PATCH 0/3] qlge: Clean up and firmware subcommands David Miller
3 siblings, 0 replies; 5+ messages in thread
From: Ron Mercer @ 2009-11-03 23:49 UTC (permalink / raw)
To: davem; +Cc: netdev, ron.mercer
Don't access netdev->stats in IO path. Save them in tx_ring/rx_rings
and add them up when get_stats API is called.
Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
---
drivers/net/qlge/qlge.h | 8 +++++++
drivers/net/qlge/qlge_main.c | 46 +++++++++++++++++++++++++++++++++++++----
2 files changed, 49 insertions(+), 5 deletions(-)
diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h
index 5e4d343..1f59f05 100644
--- a/drivers/net/qlge/qlge.h
+++ b/drivers/net/qlge/qlge.h
@@ -1263,6 +1263,9 @@ struct tx_ring {
atomic_t queue_stopped; /* Turns queue off when full. */
struct delayed_work tx_work;
struct ql_adapter *qdev;
+ u64 tx_packets;
+ u64 tx_bytes;
+ u64 tx_errors;
};
/*
@@ -1329,6 +1332,11 @@ struct rx_ring {
struct napi_struct napi;
u8 reserved;
struct ql_adapter *qdev;
+ u64 rx_packets;
+ u64 rx_multicast;
+ u64 rx_bytes;
+ u64 rx_dropped;
+ u64 rx_errors;
};
/*
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index 4a07548..0de596a 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -1661,6 +1661,7 @@ static void ql_process_mac_rx_intr(struct ql_adapter *qdev,
if (unlikely(!skb)) {
QPRINTK(qdev, RX_STATUS, DEBUG,
"No skb available, drop packet.\n");
+ rx_ring->rx_dropped++;
return;
}
@@ -1669,6 +1670,7 @@ static void ql_process_mac_rx_intr(struct ql_adapter *qdev,
QPRINTK(qdev, DRV, ERR, "Receive error, flags2 = 0x%x\n",
ib_mac_rsp->flags2);
dev_kfree_skb_any(skb);
+ rx_ring->rx_errors++;
return;
}
@@ -1677,6 +1679,7 @@ static void ql_process_mac_rx_intr(struct ql_adapter *qdev,
*/
if (skb->len > ndev->mtu + ETH_HLEN) {
dev_kfree_skb_any(skb);
+ rx_ring->rx_dropped++;
return;
}
@@ -1697,6 +1700,7 @@ static void ql_process_mac_rx_intr(struct ql_adapter *qdev,
IB_MAC_IOCB_RSP_M_REG ? "Registered" : "",
(ib_mac_rsp->flags1 & IB_MAC_IOCB_RSP_M_MASK) ==
IB_MAC_IOCB_RSP_M_PROM ? "Promiscuous" : "");
+ rx_ring->rx_multicast++;
}
if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_P) {
QPRINTK(qdev, RX_STATUS, DEBUG, "Promiscuous Packet.\n");
@@ -1728,8 +1732,8 @@ static void ql_process_mac_rx_intr(struct ql_adapter *qdev,
}
}
- ndev->stats.rx_packets++;
- ndev->stats.rx_bytes += skb->len;
+ rx_ring->rx_packets++;
+ rx_ring->rx_bytes += skb->len;
skb_record_rx_queue(skb, rx_ring->cq_id);
if (skb->ip_summed == CHECKSUM_UNNECESSARY) {
if (qdev->vlgrp &&
@@ -1753,7 +1757,6 @@ static void ql_process_mac_rx_intr(struct ql_adapter *qdev,
static void ql_process_mac_tx_intr(struct ql_adapter *qdev,
struct ob_mac_iocb_rsp *mac_rsp)
{
- struct net_device *ndev = qdev->ndev;
struct tx_ring *tx_ring;
struct tx_ring_desc *tx_ring_desc;
@@ -1761,8 +1764,8 @@ static void ql_process_mac_tx_intr(struct ql_adapter *qdev,
tx_ring = &qdev->tx_ring[mac_rsp->txq_idx];
tx_ring_desc = &tx_ring->q[mac_rsp->tid];
ql_unmap_send(qdev, tx_ring_desc, tx_ring_desc->map_cnt);
- ndev->stats.tx_bytes += (tx_ring_desc->skb)->len;
- ndev->stats.tx_packets++;
+ tx_ring->tx_bytes += (tx_ring_desc->skb)->len;
+ tx_ring->tx_packets++;
dev_kfree_skb(tx_ring_desc->skb);
tx_ring_desc->skb = NULL;
@@ -2205,6 +2208,7 @@ static netdev_tx_t qlge_send(struct sk_buff *skb, struct net_device *ndev)
__func__, tx_ring_idx);
netif_stop_subqueue(ndev, tx_ring->wq_id);
atomic_inc(&tx_ring->queue_stopped);
+ tx_ring->tx_errors++;
return NETDEV_TX_BUSY;
}
tx_ring_desc = &tx_ring->q[tx_ring->prod_idx];
@@ -2239,6 +2243,7 @@ static netdev_tx_t qlge_send(struct sk_buff *skb, struct net_device *ndev)
NETDEV_TX_OK) {
QPRINTK(qdev, TX_QUEUED, ERR,
"Could not map the segments.\n");
+ tx_ring->tx_errors++;
return NETDEV_TX_BUSY;
}
QL_DUMP_OB_MAC_IOCB(mac_iocb_ptr);
@@ -3817,6 +3822,37 @@ static int qlge_change_mtu(struct net_device *ndev, int new_mtu)
static struct net_device_stats *qlge_get_stats(struct net_device
*ndev)
{
+ struct ql_adapter *qdev = netdev_priv(ndev);
+ struct rx_ring *rx_ring = &qdev->rx_ring[0];
+ struct tx_ring *tx_ring = &qdev->tx_ring[0];
+ unsigned long pkts, mcast, dropped, errors, bytes;
+ int i;
+
+ /* Get RX stats. */
+ pkts = mcast = dropped = errors = bytes = 0;
+ for (i = 0; i < qdev->rss_ring_count; i++, rx_ring++) {
+ pkts += rx_ring->rx_packets;
+ bytes += rx_ring->rx_bytes;
+ dropped += rx_ring->rx_dropped;
+ errors += rx_ring->rx_errors;
+ mcast += rx_ring->rx_multicast;
+ }
+ ndev->stats.rx_packets = pkts;
+ ndev->stats.rx_bytes = bytes;
+ ndev->stats.rx_dropped = dropped;
+ ndev->stats.rx_errors = errors;
+ ndev->stats.multicast = mcast;
+
+ /* Get TX stats. */
+ pkts = errors = bytes = 0;
+ for (i = 0; i < qdev->tx_ring_count; i++, tx_ring++) {
+ pkts += tx_ring->tx_packets;
+ bytes += tx_ring->tx_bytes;
+ errors += tx_ring->tx_errors;
+ }
+ ndev->stats.tx_packets = pkts;
+ ndev->stats.tx_bytes = bytes;
+ ndev->stats.tx_errors = errors;
return &ndev->stats;
}
--
1.6.0.2
^ permalink raw reply related [flat|nested] 5+ messages in thread