* [PATCH 0/21][next] qlge: Clean up and add firmware support.
@ 2009-01-23 15:15 Ron Mercer
2009-01-23 15:16 ` [PATCH 01/21] [next] qlge: Change to device ID 8000 and corresponding flash access Ron Mercer
` (21 more replies)
0 siblings, 22 replies; 28+ messages in thread
From: Ron Mercer @ 2009-01-23 15:15 UTC (permalink / raw)
To: davem; +Cc: netdev, ron.mercer
Hi Dave,
This series does 3 things for 2.6.30:
1) Adds in device ID 8000. Note that it replaces 8012. We don't want to
carry forward 8012 support unless forced to. If necessary we'll add it
in disto. It was an early device that didn't have firmware support and
different flash layout.
2) Removes driver link management and adds firmware support of link
management.
3) A lot of clean up.
Cheers,
Ron
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH 01/21] [next] qlge: Change to device ID 8000 and corresponding flash access.
2009-01-23 15:15 [PATCH 0/21][next] qlge: Clean up and add firmware support Ron Mercer
@ 2009-01-23 15:16 ` Ron Mercer
2009-01-23 23:28 ` Ben Hutchings
2009-01-23 15:16 ` [PATCH 02/21] [next] qlge: Add new functions for signaling link up/down Ron Mercer
` (20 subsequent siblings)
21 siblings, 1 reply; 28+ messages in thread
From: Ron Mercer @ 2009-01-23 15:16 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-driver, ron.mercer
Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
---
drivers/net/qlge/qlge.h | 36 ++++++++++++++++++++++++++-------
drivers/net/qlge/qlge_main.c | 45 ++++++++++++++++++++++++++++++++++++-----
2 files changed, 67 insertions(+), 14 deletions(-)
diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h
index c1dadad..02c7812 100644
--- a/drivers/net/qlge/qlge.h
+++ b/drivers/net/qlge/qlge.h
@@ -28,7 +28,7 @@
} while (0)
#define QLGE_VENDOR_ID 0x1077
-#define QLGE_DEVICE_ID 0x8012
+#define QLGE_DEVICE_ID 0x8000
#define MAX_CPUS 8
#define MAX_TX_RINGS MAX_CPUS
@@ -785,17 +785,37 @@ struct mbox_params {
int out_count;
};
+
+#define FUNC0_FLASH_OFFSET 0x140200
+#define FUNC1_FLASH_OFFSET 0x140600
+
+/* Flash related data structures. */
struct flash_params {
- u8 dev_id_str[4];
- u16 size;
- u16 csum;
- u16 ver;
- u16 sub_dev_id;
+ u8 dev_id_str[4]; /* "8000" */
+ __le16 ver;
+ __le16 size;
+ __le16 csum;
+ __le16 reserved0;
+ __le16 total_size;
+ __le16 entry_count;
+ u8 data_type0;
+ u8 data_size0;
u8 mac_addr[6];
- u16 res;
+ u8 data_type1;
+ u8 data_size1;
+ u8 mac_addr1[6];
+ u8 data_type2;
+ u8 data_size2;
+ __le16 vlan_id;
+ u8 data_type3;
+ u8 data_size3;
+ __le16 last;
+ u8 reserved1[464];
+ __le16 subsys_ven_id;
+ __le16 subsys_dev_id;
+ u8 reserved2[4];
};
-
/*
* doorbell space for the rx ring context
*/
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index 16eb9dd..a530f5b 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -641,7 +641,30 @@ static void ql_enable_all_completion_interrupts(struct ql_adapter *qdev)
}
-static int ql_read_flash_word(struct ql_adapter *qdev, int offset, u32 *data)
+static int ql_validate_flash(struct ql_adapter *qdev)
+{
+ int status, i, size;
+ u16 csum = 0;
+ __le16 *flash = (__le16 *)&qdev->flash;
+
+ status = strncmp(qdev->flash.dev_id_str, "8000", 4);
+ if (status) {
+ QPRINTK(qdev, IFUP, ERR, "Invalid flash signature %s.\n",
+ qdev->flash.dev_id_str);
+ return status;
+ }
+
+ size = sizeof(struct flash_params) / sizeof(u16);
+ for (i = 0; i < size; i++)
+ csum += le16_to_cpu(*flash++);
+
+ if (csum)
+ QPRINTK(qdev, IFUP, ERR, "Invalid flash checksum.\n");
+
+ return csum;
+}
+
+static int ql_read_flash_word(struct ql_adapter *qdev, int offset, __le32 *data)
{
int status = 0;
/* wait for reg to come ready */
@@ -657,28 +680,38 @@ static int ql_read_flash_word(struct ql_adapter *qdev, int offset, u32 *data)
if (status)
goto exit;
/* get the data */
- *data = ql_read32(qdev, FLASH_DATA);
+ *data = cpu_to_le32(ql_read32(qdev, FLASH_DATA));
exit:
return status;
}
static int ql_get_flash_params(struct ql_adapter *qdev)
{
- int i;
+ u32 i;
int status;
- u32 *p = (u32 *)&qdev->flash;
+ __le32 *p = (__le32 *)&qdev->flash;
+ u32 offset;
+
+ /* Get flash offset for function and adjust
+ * for dword access.
+ */
+ if (!qdev->func)
+ offset = FUNC0_FLASH_OFFSET / sizeof(u32);
+ else
+ offset = FUNC1_FLASH_OFFSET / sizeof(u32);
if (ql_sem_spinlock(qdev, SEM_FLASH_MASK))
return -ETIMEDOUT;
for (i = 0; i < sizeof(qdev->flash) / sizeof(u32); i++, p++) {
- status = ql_read_flash_word(qdev, i, p);
+ status = ql_read_flash_word(qdev, i+offset, p);
if (status) {
QPRINTK(qdev, IFUP, ERR, "Error reading flash.\n");
goto exit;
}
-
}
+
+ status = ql_validate_flash(qdev);
exit:
ql_sem_unlock(qdev, SEM_FLASH_MASK);
return status;
--
1.6.0.2
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 02/21] [next] qlge: Add new functions for signaling link up/down.
2009-01-23 15:15 [PATCH 0/21][next] qlge: Clean up and add firmware support Ron Mercer
2009-01-23 15:16 ` [PATCH 01/21] [next] qlge: Change to device ID 8000 and corresponding flash access Ron Mercer
@ 2009-01-23 15:16 ` Ron Mercer
2009-01-23 23:23 ` Ben Hutchings
2009-01-23 15:16 ` [PATCH 03/21] [next] qlge: Clean and optimize rx buf queue refill Ron Mercer
` (19 subsequent siblings)
21 siblings, 1 reply; 28+ messages in thread
From: Ron Mercer @ 2009-01-23 15:16 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-driver, ron.mercer
Centralize this call as it will also be used by firmware events.
Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
---
drivers/net/qlge/qlge_main.c | 38 ++++++++++++++++++++++++--------------
1 files changed, 24 insertions(+), 14 deletions(-)
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index a530f5b..e6f9146 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -240,6 +240,24 @@ exit:
return status;
}
+static void ql_link_on(struct ql_adapter *qdev)
+{
+ if (!netif_carrier_ok(qdev->ndev)) {
+ QPRINTK(qdev, LINK, INFO, "Link is Up.\n");
+ netif_carrier_on(qdev->ndev);
+ netif_wake_queue(qdev->ndev);
+ }
+}
+
+static void ql_link_off(struct ql_adapter *qdev)
+{
+ if (netif_carrier_ok(qdev->ndev)) {
+ QPRINTK(qdev, LINK, INFO, "Link is Down.\n");
+ netif_carrier_off(qdev->ndev);
+ netif_stop_queue(qdev->ndev);
+ }
+}
+
/* Get a specific MAC address from the CAM. Used for debug and reg dump. */
int ql_get_mac_addr_reg(struct ql_adapter *qdev, u32 type, u16 index,
u32 *value)
@@ -1524,15 +1542,13 @@ static void ql_process_mac_tx_intr(struct ql_adapter *qdev,
/* Fire up a handler to reset the MPI processor. */
void ql_queue_fw_error(struct ql_adapter *qdev)
{
- netif_stop_queue(qdev->ndev);
- netif_carrier_off(qdev->ndev);
+ ql_link_off(qdev);
queue_delayed_work(qdev->workqueue, &qdev->mpi_reset_work, 0);
}
void ql_queue_asic_error(struct ql_adapter *qdev)
{
- netif_stop_queue(qdev->ndev);
- netif_carrier_off(qdev->ndev);
+ ql_link_off(qdev);
ql_disable_interrupts(qdev);
queue_delayed_work(qdev->workqueue, &qdev->asic_reset_work, 0);
}
@@ -3116,12 +3132,10 @@ static void ql_display_dev_info(struct net_device *ndev)
static int ql_adapter_down(struct ql_adapter *qdev)
{
- struct net_device *ndev = qdev->ndev;
int i, status = 0;
struct rx_ring *rx_ring;
- netif_stop_queue(ndev);
- netif_carrier_off(ndev);
+ ql_link_off(qdev);
cancel_delayed_work_sync(&qdev->asic_reset_work);
cancel_delayed_work_sync(&qdev->mpi_reset_work);
@@ -3179,11 +3193,8 @@ static int ql_adapter_up(struct ql_adapter *qdev)
set_bit(QL_ADAPTER_UP, &qdev->flags);
ql_enable_interrupts(qdev);
ql_enable_all_completion_interrupts(qdev);
- if ((ql_read32(qdev, STS) & qdev->port_init)) {
- netif_carrier_on(qdev->ndev);
- netif_start_queue(qdev->ndev);
- }
-
+ if ((ql_read32(qdev, STS) & qdev->port_init))
+ ql_link_on(qdev);
return 0;
err_init:
ql_adapter_reset(qdev);
@@ -3816,8 +3827,7 @@ static pci_ers_result_t qlge_io_slot_reset(struct pci_dev *pdev)
pci_set_master(pdev);
- netif_carrier_off(ndev);
- netif_stop_queue(ndev);
+ ql_link_off(qdev);
ql_adapter_reset(qdev);
/* Make sure the EEPROM is good */
--
1.6.0.2
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 03/21] [next] qlge: Clean and optimize rx buf queue refill.
2009-01-23 15:15 [PATCH 0/21][next] qlge: Clean up and add firmware support Ron Mercer
2009-01-23 15:16 ` [PATCH 01/21] [next] qlge: Change to device ID 8000 and corresponding flash access Ron Mercer
2009-01-23 15:16 ` [PATCH 02/21] [next] qlge: Add new functions for signaling link up/down Ron Mercer
@ 2009-01-23 15:16 ` Ron Mercer
2009-01-23 15:16 ` [PATCH 04/21] [next] qlge: Clean up adapter reset function Ron Mercer
` (18 subsequent siblings)
21 siblings, 0 replies; 28+ messages in thread
From: Ron Mercer @ 2009-01-23 15:16 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-driver, ron.mercer
Rx buffers are passed to the chip in chunks of 16. This patch
causes the queue to be updated once at the end instead of every
16 buffers.
Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
---
drivers/net/qlge/qlge_main.c | 41 +++++++++++++++++++++++++++--------------
1 files changed, 27 insertions(+), 14 deletions(-)
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index e6f9146..340a8ac 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -922,8 +922,10 @@ static void ql_write_cq_idx(struct rx_ring *rx_ring)
/* Process (refill) a large buffer queue. */
static void ql_update_lbq(struct ql_adapter *qdev, struct rx_ring *rx_ring)
{
- int clean_idx = rx_ring->lbq_clean_idx;
+ u32 clean_idx = rx_ring->lbq_clean_idx;
+ u32 start_idx = clean_idx;
struct bq_desc *lbq_desc;
+ struct page *page;
u64 map;
int i;
@@ -937,19 +939,22 @@ static void ql_update_lbq(struct ql_adapter *qdev, struct rx_ring *rx_ring)
QPRINTK(qdev, RX_STATUS, DEBUG,
"lbq: getting new page for index %d.\n",
lbq_desc->index);
- lbq_desc->p.lbq_page = alloc_page(GFP_ATOMIC);
- if (lbq_desc->p.lbq_page == NULL) {
- QPRINTK(qdev, RX_STATUS, ERR,
+ page = alloc_page(GFP_ATOMIC);
+ if (page == NULL) {
+ QPRINTK(qdev, DRV, ERR,
"Couldn't get a page.\n");
return;
}
+ lbq_desc->p.lbq_page = page;
map = pci_map_page(qdev->pdev,
- lbq_desc->p.lbq_page,
+ page,
0, PAGE_SIZE,
PCI_DMA_FROMDEVICE);
if (pci_dma_mapping_error(qdev->pdev, map)) {
- QPRINTK(qdev, RX_STATUS, ERR,
+ QPRINTK(qdev, DRV, ERR,
"PCI mapping failed.\n");
+ put_page(page);
+ lbq_desc->p.lbq_page = NULL;
return;
}
pci_unmap_addr_set(lbq_desc, mapaddr, map);
@@ -965,20 +970,25 @@ static void ql_update_lbq(struct ql_adapter *qdev, struct rx_ring *rx_ring)
rx_ring->lbq_prod_idx += 16;
if (rx_ring->lbq_prod_idx == rx_ring->lbq_len)
rx_ring->lbq_prod_idx = 0;
+ rx_ring->lbq_free_cnt -= 16;
+ }
+
+ if (start_idx != clean_idx) {
QPRINTK(qdev, RX_STATUS, DEBUG,
"lbq: updating prod idx = %d.\n",
rx_ring->lbq_prod_idx);
ql_write_db_reg(rx_ring->lbq_prod_idx,
rx_ring->lbq_prod_idx_db_reg);
- rx_ring->lbq_free_cnt -= 16;
}
}
/* Process (refill) a small buffer queue. */
static void ql_update_sbq(struct ql_adapter *qdev, struct rx_ring *rx_ring)
{
- int clean_idx = rx_ring->sbq_clean_idx;
+ u32 clean_idx = rx_ring->sbq_clean_idx;
+ u32 start_idx = clean_idx;
struct bq_desc *sbq_desc;
+ struct sk_buff *skb;
u64 map;
int i;
@@ -992,18 +1002,19 @@ static void ql_update_sbq(struct ql_adapter *qdev, struct rx_ring *rx_ring)
QPRINTK(qdev, RX_STATUS, DEBUG,
"sbq: getting new skb for index %d.\n",
sbq_desc->index);
- sbq_desc->p.skb =
+ skb =
netdev_alloc_skb(qdev->ndev,
rx_ring->sbq_buf_size);
- if (sbq_desc->p.skb == NULL) {
+ if (skb == NULL) {
QPRINTK(qdev, PROBE, ERR,
"Couldn't get an skb.\n");
rx_ring->sbq_clean_idx = clean_idx;
return;
}
- skb_reserve(sbq_desc->p.skb, QLGE_SB_PAD);
+ sbq_desc->p.skb = skb;
+ skb_reserve(skb, QLGE_SB_PAD);
map = pci_map_single(qdev->pdev,
- sbq_desc->p.skb->data,
+ skb->data,
rx_ring->sbq_buf_size /
2, PCI_DMA_FROMDEVICE);
if (pci_dma_mapping_error(qdev->pdev, map)) {
@@ -1025,13 +1036,15 @@ static void ql_update_sbq(struct ql_adapter *qdev, struct rx_ring *rx_ring)
rx_ring->sbq_prod_idx += 16;
if (rx_ring->sbq_prod_idx == rx_ring->sbq_len)
rx_ring->sbq_prod_idx = 0;
+ rx_ring->sbq_free_cnt -= 16;
+ }
+
+ if (start_idx != clean_idx) {
QPRINTK(qdev, RX_STATUS, DEBUG,
"sbq: updating prod idx = %d.\n",
rx_ring->sbq_prod_idx);
ql_write_db_reg(rx_ring->sbq_prod_idx,
rx_ring->sbq_prod_idx_db_reg);
-
- rx_ring->sbq_free_cnt -= 16;
}
}
--
1.6.0.2
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 04/21] [next] qlge: Clean up adapter reset function.
2009-01-23 15:15 [PATCH 0/21][next] qlge: Clean up and add firmware support Ron Mercer
` (2 preceding siblings ...)
2009-01-23 15:16 ` [PATCH 03/21] [next] qlge: Clean and optimize rx buf queue refill Ron Mercer
@ 2009-01-23 15:16 ` Ron Mercer
2009-01-23 15:16 ` [PATCH 05/21] [next] qlge: Add new function for MAC address and frame routing Ron Mercer
` (17 subsequent siblings)
21 siblings, 0 replies; 28+ messages in thread
From: Ron Mercer @ 2009-01-23 15:16 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-driver, ron.mercer
Remove some debug junk.
Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
---
drivers/net/qlge/qlge_main.c | 23 +++++------------------
1 files changed, 5 insertions(+), 18 deletions(-)
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index 340a8ac..60d3c31 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -3093,36 +3093,23 @@ static int ql_adapter_initialize(struct ql_adapter *qdev)
static int ql_adapter_reset(struct ql_adapter *qdev)
{
u32 value;
- int max_wait_time;
+ int max_wait_time = 3;
int status = 0;
- int resetCnt = 0;
-#define MAX_RESET_CNT 1
-issueReset:
- resetCnt++;
- QPRINTK(qdev, IFDOWN, DEBUG, "Issue soft reset to chip.\n");
ql_write32(qdev, RST_FO, (RST_FO_FR << 16) | RST_FO_FR);
- /* Wait for reset to complete. */
+
max_wait_time = 3;
- QPRINTK(qdev, IFDOWN, DEBUG, "Wait %d seconds for reset to complete.\n",
- max_wait_time);
do {
value = ql_read32(qdev, RST_FO);
if ((value & RST_FO_FR) == 0)
break;
-
- ssleep(1);
+ udelay(10);
} while ((--max_wait_time));
- if (value & RST_FO_FR) {
- QPRINTK(qdev, IFDOWN, ERR,
- "Stuck in SoftReset: FSC_SR:0x%08x\n", value);
- if (resetCnt < MAX_RESET_CNT)
- goto issueReset;
- }
+
if (max_wait_time == 0) {
- status = -ETIMEDOUT;
QPRINTK(qdev, IFDOWN, ERR,
"ETIMEOUT!!! errored out of resetting the chip!\n");
+ status = -ETIMEDOUT;
}
return status;
--
1.6.0.2
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 05/21] [next] qlge: Add new function for MAC address and frame routing.
2009-01-23 15:15 [PATCH 0/21][next] qlge: Clean up and add firmware support Ron Mercer
` (3 preceding siblings ...)
2009-01-23 15:16 ` [PATCH 04/21] [next] qlge: Clean up adapter reset function Ron Mercer
@ 2009-01-23 15:16 ` Ron Mercer
2009-01-23 15:16 ` [PATCH 06/21] [next] qlge: Expand granularity on holding hardware semaphore Ron Mercer
` (16 subsequent siblings)
21 siblings, 0 replies; 28+ messages in thread
From: Ron Mercer @ 2009-01-23 15:16 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-driver, ron.mercer
This code needs to be centralized as it will later be called
in response to firmware events.
Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
---
drivers/net/qlge/qlge_main.c | 31 ++++++++++++++++++++++---------
1 files changed, 22 insertions(+), 9 deletions(-)
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index 60d3c31..236597d 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -2996,6 +2996,24 @@ static int ql_route_initialize(struct ql_adapter *qdev)
return status;
}
+static int ql_cam_route_initialize(struct ql_adapter *qdev)
+{
+ int status;
+
+ status = ql_set_mac_addr_reg(qdev, (u8 *) qdev->ndev->perm_addr,
+ MAC_ADDR_TYPE_CAM_MAC, qdev->func * MAX_CQ);
+ if (status) {
+ QPRINTK(qdev, IFUP, ERR, "Failed to init mac address.\n");
+ return status;
+ }
+
+ status = ql_route_initialize(qdev);
+ if (status)
+ QPRINTK(qdev, IFUP, ERR, "Failed to init routing table.\n");
+
+ return status;
+}
+
static int ql_adapter_initialize(struct ql_adapter *qdev)
{
u32 value, mask;
@@ -3066,16 +3084,11 @@ static int ql_adapter_initialize(struct ql_adapter *qdev)
return status;
}
- status = ql_set_mac_addr_reg(qdev, (u8 *) qdev->ndev->perm_addr,
- MAC_ADDR_TYPE_CAM_MAC, qdev->func);
- if (status) {
- QPRINTK(qdev, IFUP, ERR, "Failed to init mac address.\n");
- return status;
- }
-
- status = ql_route_initialize(qdev);
+ /* Set up the MAC address and frame routing filter. */
+ status = ql_cam_route_initialize(qdev);
if (status) {
- QPRINTK(qdev, IFUP, ERR, "Failed to init routing table.\n");
+ QPRINTK(qdev, IFUP, ERR,
+ "Failed to init CAM/Routing tables.\n");
return status;
}
--
1.6.0.2
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 06/21] [next] qlge: Expand granularity on holding hardware semaphore.
2009-01-23 15:15 [PATCH 0/21][next] qlge: Clean up and add firmware support Ron Mercer
` (4 preceding siblings ...)
2009-01-23 15:16 ` [PATCH 05/21] [next] qlge: Add new function for MAC address and frame routing Ron Mercer
@ 2009-01-23 15:16 ` Ron Mercer
2009-01-23 15:16 ` [PATCH 07/21] [next] qlge: Remove lock protection in adapter up/down Ron Mercer
` (15 subsequent siblings)
21 siblings, 0 replies; 28+ messages in thread
From: Ron Mercer @ 2009-01-23 15:16 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-driver, ron.mercer
This semaphore must be held when we change frame routing, MAC
addresses etc. In many cases several values will be changed
iteratively. This patch causes the sem to be held until all
values are changed, rather than take/give for each value.
Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
---
drivers/net/qlge/qlge_dbg.c | 12 +++++++
drivers/net/qlge/qlge_main.c | 71 +++++++++++++++++++++++++-----------------
2 files changed, 54 insertions(+), 29 deletions(-)
diff --git a/drivers/net/qlge/qlge_dbg.c b/drivers/net/qlge/qlge_dbg.c
index 379b895..cdf12d3 100644
--- a/drivers/net/qlge/qlge_dbg.c
+++ b/drivers/net/qlge/qlge_dbg.c
@@ -83,6 +83,11 @@ static void ql_dump_cam_entries(struct ql_adapter *qdev)
{
int i;
u32 value[3];
+
+ i = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
+ if (i)
+ return;
+
for (i = 0; i < 4; i++) {
if (ql_get_mac_addr_reg(qdev, MAC_ADDR_TYPE_CAM_MAC, i, value)) {
printk(KERN_ERR PFX
@@ -111,12 +116,18 @@ static void ql_dump_cam_entries(struct ql_adapter *qdev)
qdev->ndev->name, i, value[1], value[0]);
}
}
+ ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
}
void ql_dump_routing_entries(struct ql_adapter *qdev)
{
int i;
u32 value;
+
+ i = ql_sem_spinlock(qdev, SEM_RT_IDX_MASK);
+ if (i)
+ return;
+
for (i = 0; i < 16; i++) {
value = 0;
if (ql_get_routing_reg(qdev, i, &value)) {
@@ -131,6 +142,7 @@ void ql_dump_routing_entries(struct ql_adapter *qdev)
qdev->ndev->name, i, value);
}
}
+ ql_sem_unlock(qdev, SEM_RT_IDX_MASK);
}
void ql_dump_regs(struct ql_adapter *qdev)
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index 236597d..0db99b4 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -265,9 +265,6 @@ int ql_get_mac_addr_reg(struct ql_adapter *qdev, u32 type, u16 index,
u32 offset = 0;
int status;
- status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
- if (status)
- return status;
switch (type) {
case MAC_ADDR_TYPE_MULTI_MAC:
case MAC_ADDR_TYPE_CAM_MAC:
@@ -326,7 +323,6 @@ int ql_get_mac_addr_reg(struct ql_adapter *qdev, u32 type, u16 index,
status = -EPERM;
}
exit:
- ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
return status;
}
@@ -339,9 +335,6 @@ static int ql_set_mac_addr_reg(struct ql_adapter *qdev, u8 *addr, u32 type,
u32 offset = 0;
int status = 0;
- status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
- if (status)
- return status;
switch (type) {
case MAC_ADDR_TYPE_MULTI_MAC:
case MAC_ADDR_TYPE_CAM_MAC:
@@ -433,7 +426,6 @@ static int ql_set_mac_addr_reg(struct ql_adapter *qdev, u8 *addr, u32 type,
status = -EPERM;
}
exit:
- ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
return status;
}
@@ -444,10 +436,6 @@ int ql_get_routing_reg(struct ql_adapter *qdev, u32 index, u32 *value)
{
int status = 0;
- status = ql_sem_spinlock(qdev, SEM_RT_IDX_MASK);
- if (status)
- goto exit;
-
status = ql_wait_reg_rdy(qdev, RT_IDX, RT_IDX_MW, 0);
if (status)
goto exit;
@@ -459,7 +447,6 @@ int ql_get_routing_reg(struct ql_adapter *qdev, u32 index, u32 *value)
goto exit;
*value = ql_read32(qdev, RT_DATA);
exit:
- ql_sem_unlock(qdev, SEM_RT_IDX_MASK);
return status;
}
@@ -474,10 +461,6 @@ static int ql_set_routing_reg(struct ql_adapter *qdev, u32 index, u32 mask,
int status;
u32 value = 0;
- status = ql_sem_spinlock(qdev, SEM_RT_IDX_MASK);
- if (status)
- return status;
-
QPRINTK(qdev, IFUP, DEBUG,
"%s %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s mask %s the routing reg.\n",
(enable ? "Adding" : "Removing"),
@@ -573,7 +556,6 @@ static int ql_set_routing_reg(struct ql_adapter *qdev, u32 index, u32 mask,
ql_write32(qdev, RT_DATA, enable ? mask : 0);
}
exit:
- ql_sem_unlock(qdev, SEM_RT_IDX_MASK);
return status;
}
@@ -1730,19 +1712,29 @@ static void ql_vlan_rx_add_vid(struct net_device *ndev, u16 vid)
{
struct ql_adapter *qdev = netdev_priv(ndev);
u32 enable_bit = MAC_ADDR_E;
+ int status;
+ status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
+ if (status)
+ return;
spin_lock(&qdev->hw_lock);
if (ql_set_mac_addr_reg
(qdev, (u8 *) &enable_bit, MAC_ADDR_TYPE_VLAN, vid)) {
QPRINTK(qdev, IFUP, ERR, "Failed to init vlan address.\n");
}
spin_unlock(&qdev->hw_lock);
+ ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
}
static void ql_vlan_rx_kill_vid(struct net_device *ndev, u16 vid)
{
struct ql_adapter *qdev = netdev_priv(ndev);
u32 enable_bit = 0;
+ int status;
+
+ status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
+ if (status)
+ return;
spin_lock(&qdev->hw_lock);
if (ql_set_mac_addr_reg
@@ -1750,6 +1742,7 @@ static void ql_vlan_rx_kill_vid(struct net_device *ndev, u16 vid)
QPRINTK(qdev, IFUP, ERR, "Failed to clear vlan address.\n");
}
spin_unlock(&qdev->hw_lock);
+ ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
}
@@ -2951,13 +2944,17 @@ static int ql_route_initialize(struct ql_adapter *qdev)
int status = 0;
int i;
+ status = ql_sem_spinlock(qdev, SEM_RT_IDX_MASK);
+ if (status)
+ return status;
+
/* Clear all the entries in the routing table. */
for (i = 0; i < 16; i++) {
status = ql_set_routing_reg(qdev, i, 0, 0);
if (status) {
QPRINTK(qdev, IFUP, ERR,
"Failed to init routing register for CAM packets.\n");
- return status;
+ goto exit;
}
}
@@ -2965,13 +2962,13 @@ static int ql_route_initialize(struct ql_adapter *qdev)
if (status) {
QPRINTK(qdev, IFUP, ERR,
"Failed to init routing register for error packets.\n");
- return status;
+ goto exit;
}
status = ql_set_routing_reg(qdev, RT_IDX_BCAST_SLOT, RT_IDX_BCAST, 1);
if (status) {
QPRINTK(qdev, IFUP, ERR,
"Failed to init routing register for broadcast packets.\n");
- return status;
+ goto exit;
}
/* If we have more than one inbound queue, then turn on RSS in the
* routing block.
@@ -2982,17 +2979,17 @@ static int ql_route_initialize(struct ql_adapter *qdev)
if (status) {
QPRINTK(qdev, IFUP, ERR,
"Failed to init routing register for MATCH RSS packets.\n");
- return status;
+ goto exit;
}
}
status = ql_set_routing_reg(qdev, RT_IDX_CAM_HIT_SLOT,
RT_IDX_CAM_HIT, 1);
- if (status) {
+ if (status)
QPRINTK(qdev, IFUP, ERR,
"Failed to init routing register for CAM packets.\n");
- return status;
- }
+exit:
+ ql_sem_unlock(qdev, SEM_RT_IDX_MASK);
return status;
}
@@ -3000,8 +2997,12 @@ static int ql_cam_route_initialize(struct ql_adapter *qdev)
{
int status;
+ status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
+ if (status)
+ return status;
status = ql_set_mac_addr_reg(qdev, (u8 *) qdev->ndev->perm_addr,
MAC_ADDR_TYPE_CAM_MAC, qdev->func * MAX_CQ);
+ ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
if (status) {
QPRINTK(qdev, IFUP, ERR, "Failed to init mac address.\n");
return status;
@@ -3444,8 +3445,11 @@ static void qlge_set_multicast_list(struct net_device *ndev)
{
struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev);
struct dev_mc_list *mc_ptr;
- int i;
+ int i, status;
+ status = ql_sem_spinlock(qdev, SEM_RT_IDX_MASK);
+ if (status)
+ return;
spin_lock(&qdev->hw_lock);
/*
* Set or clear promiscuous mode if a
@@ -3501,14 +3505,21 @@ static void qlge_set_multicast_list(struct net_device *ndev)
}
if (ndev->mc_count) {
+ status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
+ if (status)
+ goto exit;
for (i = 0, mc_ptr = ndev->mc_list; mc_ptr;
- i++, mc_ptr = mc_ptr->next)
- if (ql_set_mac_addr_reg(qdev, (u8 *) mc_ptr->dmi_addr,
- MAC_ADDR_TYPE_MULTI_MAC, i)) {
+ i++, mc_ptr = mc_ptr->next) {
+ status = ql_set_mac_addr_reg(qdev,
+ (u8 *) mc_ptr->dmi_addr,
+ MAC_ADDR_TYPE_MULTI_MAC, i);
+ if (status) {
QPRINTK(qdev, HW, ERR,
"Failed to loadmulticast address.\n");
+ ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
goto exit;
}
+ }
if (ql_set_routing_reg
(qdev, RT_IDX_MCAST_MATCH_SLOT, RT_IDX_MCAST_MATCH, 1)) {
QPRINTK(qdev, HW, ERR,
@@ -3516,9 +3527,11 @@ static void qlge_set_multicast_list(struct net_device *ndev)
} else {
set_bit(QL_ALLMULTI, &qdev->flags);
}
+ ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
}
exit:
spin_unlock(&qdev->hw_lock);
+ ql_sem_unlock(qdev, SEM_RT_IDX_MASK);
}
static int qlge_set_mac_address(struct net_device *ndev, void *p)
--
1.6.0.2
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 07/21] [next] qlge: Remove lock protection in adapter up/down.
2009-01-23 15:15 [PATCH 0/21][next] qlge: Clean up and add firmware support Ron Mercer
` (5 preceding siblings ...)
2009-01-23 15:16 ` [PATCH 06/21] [next] qlge: Expand granularity on holding hardware semaphore Ron Mercer
@ 2009-01-23 15:16 ` Ron Mercer
2009-01-23 15:16 ` [PATCH 08/21] [next] qlge: Move interrupt enable to end of adapter up function Ron Mercer
` (14 subsequent siblings)
21 siblings, 0 replies; 28+ messages in thread
From: Ron Mercer @ 2009-01-23 15:16 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-driver, ron.mercer
There is nothing to contend at these points.
Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
---
drivers/net/qlge/qlge_main.c | 5 -----
1 files changed, 0 insertions(+), 5 deletions(-)
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index 0db99b4..97b72a6 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -3183,12 +3183,10 @@ static int ql_adapter_down(struct ql_adapter *qdev)
ql_tx_ring_clean(qdev);
- spin_lock(&qdev->hw_lock);
status = ql_adapter_reset(qdev);
if (status)
QPRINTK(qdev, IFDOWN, ERR, "reset(func #%d) FAILED!\n",
qdev->func);
- spin_unlock(&qdev->hw_lock);
return status;
}
@@ -3196,14 +3194,11 @@ static int ql_adapter_up(struct ql_adapter *qdev)
{
int err = 0;
- spin_lock(&qdev->hw_lock);
err = ql_adapter_initialize(qdev);
if (err) {
QPRINTK(qdev, IFUP, INFO, "Unable to initialize adapter.\n");
- spin_unlock(&qdev->hw_lock);
goto err_init;
}
- spin_unlock(&qdev->hw_lock);
set_bit(QL_ADAPTER_UP, &qdev->flags);
ql_enable_interrupts(qdev);
ql_enable_all_completion_interrupts(qdev);
--
1.6.0.2
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 08/21] [next] qlge: Move interrupt enable to end of adapter up function.
2009-01-23 15:15 [PATCH 0/21][next] qlge: Clean up and add firmware support Ron Mercer
` (6 preceding siblings ...)
2009-01-23 15:16 ` [PATCH 07/21] [next] qlge: Remove lock protection in adapter up/down Ron Mercer
@ 2009-01-23 15:16 ` Ron Mercer
2009-01-23 15:16 ` [PATCH 09/21] [next] qlge: Upgrade print priority for hardware event handler Ron Mercer
` (13 subsequent siblings)
21 siblings, 0 replies; 28+ messages in thread
From: Ron Mercer @ 2009-01-23 15:16 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-driver, ron.mercer
Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
---
drivers/net/qlge/qlge_main.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index 97b72a6..f273160 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -3200,10 +3200,10 @@ static int ql_adapter_up(struct ql_adapter *qdev)
goto err_init;
}
set_bit(QL_ADAPTER_UP, &qdev->flags);
- ql_enable_interrupts(qdev);
ql_enable_all_completion_interrupts(qdev);
if ((ql_read32(qdev, STS) & qdev->port_init))
ql_link_on(qdev);
+ ql_enable_interrupts(qdev);
return 0;
err_init:
ql_adapter_reset(qdev);
--
1.6.0.2
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 09/21] [next] qlge: Upgrade print priority for hardware event handler.
2009-01-23 15:15 [PATCH 0/21][next] qlge: Clean up and add firmware support Ron Mercer
` (7 preceding siblings ...)
2009-01-23 15:16 ` [PATCH 08/21] [next] qlge: Move interrupt enable to end of adapter up function Ron Mercer
@ 2009-01-23 15:16 ` Ron Mercer
2009-01-23 15:16 ` [PATCH 10/21] [next] qlge: Cleanup rx buffer allocations Ron Mercer
` (12 subsequent siblings)
21 siblings, 0 replies; 28+ messages in thread
From: Ron Mercer @ 2009-01-23 15:16 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-driver, ron.mercer
These events indicate errors and should have higher
priority logging.
Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
---
drivers/net/qlge/qlge_main.c | 11 ++++++-----
1 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index f273160..f3fa375 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -1553,26 +1553,27 @@ static void ql_process_chip_ae_intr(struct ql_adapter *qdev,
{
switch (ib_ae_rsp->event) {
case MGMT_ERR_EVENT:
- QPRINTK(qdev, RX_ERR, ERR,
+ QPRINTK(qdev, DRV, ERR,
"Management Processor Fatal Error.\n");
ql_queue_fw_error(qdev);
return;
case CAM_LOOKUP_ERR_EVENT:
- QPRINTK(qdev, LINK, ERR,
+ QPRINTK(qdev, DRV, ERR,
"Multiple CAM hits lookup occurred.\n");
QPRINTK(qdev, DRV, ERR, "This event shouldn't occur.\n");
ql_queue_asic_error(qdev);
return;
case SOFT_ECC_ERROR_EVENT:
- QPRINTK(qdev, RX_ERR, ERR, "Soft ECC error detected.\n");
+ QPRINTK(qdev, DRV, ERR, "Soft ECC error detected.\n");
ql_queue_asic_error(qdev);
break;
case PCI_ERR_ANON_BUF_RD:
- QPRINTK(qdev, RX_ERR, ERR,
- "PCI error occurred when reading anonymous buffers from rx_ring %d.\n",
+ QPRINTK(qdev, DRV, ERR,
+ "PCI error occurred when reading anonymous "
+ "buffers from rx_ring %d.\n",
ib_ae_rsp->q_id);
ql_queue_asic_error(qdev);
break;
--
1.6.0.2
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 10/21] [next] qlge: Cleanup rx buffer allocations.
2009-01-23 15:15 [PATCH 0/21][next] qlge: Clean up and add firmware support Ron Mercer
` (8 preceding siblings ...)
2009-01-23 15:16 ` [PATCH 09/21] [next] qlge: Upgrade print priority for hardware event handler Ron Mercer
@ 2009-01-23 15:16 ` Ron Mercer
2009-01-23 15:16 ` [PATCH 11/21] [next] qlge: Cleanup spin lock usage for some register accesses Ron Mercer
` (11 subsequent siblings)
21 siblings, 0 replies; 28+ messages in thread
From: Ron Mercer @ 2009-01-23 15:16 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-driver, ron.mercer
There were two paths to fill rx buffer queues. One used during
initialization and another at runtime. This patch causes the
same code to be used in both places.
Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
---
drivers/net/qlge/qlge_main.c | 184 ++++++++++++++---------------------------
1 files changed, 63 insertions(+), 121 deletions(-)
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index f3fa375..55c0f91 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -2125,7 +2125,7 @@ static void ql_free_lbq_buffers(struct ql_adapter *qdev, struct rx_ring *rx_ring
for (i = 0; i < rx_ring->lbq_len; i++) {
lbq_desc = &rx_ring->lbq[i];
- if (lbq_desc->p.lbq_page) {
+ if (lbq_desc && lbq_desc->p.lbq_page) {
pci_unmap_page(qdev->pdev,
pci_unmap_addr(lbq_desc, mapaddr),
pci_unmap_len(lbq_desc, maplen),
@@ -2137,47 +2137,6 @@ static void ql_free_lbq_buffers(struct ql_adapter *qdev, struct rx_ring *rx_ring
}
}
-/*
- * Allocate and map a page for each element of the lbq.
- */
-static int ql_alloc_lbq_buffers(struct ql_adapter *qdev,
- struct rx_ring *rx_ring)
-{
- int i;
- struct bq_desc *lbq_desc;
- u64 map;
- __le64 *bq = rx_ring->lbq_base;
-
- for (i = 0; i < rx_ring->lbq_len; i++) {
- lbq_desc = &rx_ring->lbq[i];
- memset(lbq_desc, 0, sizeof(lbq_desc));
- lbq_desc->addr = bq;
- lbq_desc->index = i;
- lbq_desc->p.lbq_page = alloc_page(GFP_ATOMIC);
- if (unlikely(!lbq_desc->p.lbq_page)) {
- QPRINTK(qdev, IFUP, ERR, "failed alloc_page().\n");
- goto mem_error;
- } else {
- map = pci_map_page(qdev->pdev,
- lbq_desc->p.lbq_page,
- 0, PAGE_SIZE, PCI_DMA_FROMDEVICE);
- if (pci_dma_mapping_error(qdev->pdev, map)) {
- QPRINTK(qdev, IFUP, ERR,
- "PCI mapping failed.\n");
- goto mem_error;
- }
- pci_unmap_addr_set(lbq_desc, mapaddr, map);
- pci_unmap_len_set(lbq_desc, maplen, PAGE_SIZE);
- *lbq_desc->addr = cpu_to_le64(map);
- }
- bq++;
- }
- return 0;
-mem_error:
- ql_free_lbq_buffers(qdev, rx_ring);
- return -ENOMEM;
-}
-
static void ql_free_sbq_buffers(struct ql_adapter *qdev, struct rx_ring *rx_ring)
{
int i;
@@ -2185,11 +2144,7 @@ static void ql_free_sbq_buffers(struct ql_adapter *qdev, struct rx_ring *rx_ring
for (i = 0; i < rx_ring->sbq_len; i++) {
sbq_desc = &rx_ring->sbq[i];
- if (sbq_desc == NULL) {
- QPRINTK(qdev, IFUP, ERR, "sbq_desc %d is NULL.\n", i);
- return;
- }
- if (sbq_desc->p.skb) {
+ if (sbq_desc && sbq_desc->p.skb) {
pci_unmap_single(qdev->pdev,
pci_unmap_addr(sbq_desc, mapaddr),
pci_unmap_len(sbq_desc, maplen),
@@ -2200,63 +2155,68 @@ static void ql_free_sbq_buffers(struct ql_adapter *qdev, struct rx_ring *rx_ring
}
}
-/* Allocate and map an skb for each element of the sbq. */
-static int ql_alloc_sbq_buffers(struct ql_adapter *qdev,
+static void ql_free_rx_buffers(struct ql_adapter *qdev)
+{
+ int i;
+ struct rx_ring *rx_ring;
+
+ for (i = 0; i < qdev->rx_ring_count; i++) {
+ rx_ring = &qdev->rx_ring[i];
+ if (rx_ring->lbq)
+ ql_free_lbq_buffers(qdev, rx_ring);
+ if (rx_ring->sbq)
+ ql_free_sbq_buffers(qdev, rx_ring);
+ }
+}
+
+static void ql_alloc_rx_buffers(struct ql_adapter *qdev)
+{
+ struct rx_ring *rx_ring;
+ int i;
+
+ for (i = 0; i < qdev->rx_ring_count; i++) {
+ rx_ring = &qdev->rx_ring[i];
+ if (rx_ring->type != TX_Q)
+ ql_update_buffer_queues(qdev, rx_ring);
+ }
+}
+
+static void ql_init_lbq_ring(struct ql_adapter *qdev,
+ struct rx_ring *rx_ring)
+{
+ int i;
+ struct bq_desc *lbq_desc;
+ __le64 *bq = rx_ring->lbq_base;
+
+ memset(rx_ring->lbq, 0, rx_ring->lbq_len * sizeof(struct bq_desc));
+ for (i = 0; i < rx_ring->lbq_len; i++) {
+ lbq_desc = &rx_ring->lbq[i];
+ memset(lbq_desc, 0, sizeof(lbq_desc));
+ lbq_desc->index = i;
+ lbq_desc->addr = bq;
+ bq++;
+ }
+}
+
+static void ql_init_sbq_ring(struct ql_adapter *qdev,
struct rx_ring *rx_ring)
{
int i;
struct bq_desc *sbq_desc;
- struct sk_buff *skb;
- u64 map;
__le64 *bq = rx_ring->sbq_base;
+ memset(rx_ring->sbq, 0, rx_ring->sbq_len * sizeof(struct bq_desc));
for (i = 0; i < rx_ring->sbq_len; i++) {
sbq_desc = &rx_ring->sbq[i];
memset(sbq_desc, 0, sizeof(sbq_desc));
sbq_desc->index = i;
sbq_desc->addr = bq;
- skb = netdev_alloc_skb(qdev->ndev, rx_ring->sbq_buf_size);
- if (unlikely(!skb)) {
- /* Better luck next round */
- QPRINTK(qdev, IFUP, ERR,
- "small buff alloc failed for %d bytes at index %d.\n",
- rx_ring->sbq_buf_size, i);
- goto mem_err;
- }
- skb_reserve(skb, QLGE_SB_PAD);
- sbq_desc->p.skb = skb;
- /*
- * Map only half the buffer. Because the
- * other half may get some data copied to it
- * when the completion arrives.
- */
- map = pci_map_single(qdev->pdev,
- skb->data,
- rx_ring->sbq_buf_size / 2,
- PCI_DMA_FROMDEVICE);
- if (pci_dma_mapping_error(qdev->pdev, map)) {
- QPRINTK(qdev, IFUP, ERR, "PCI mapping failed.\n");
- goto mem_err;
- }
- pci_unmap_addr_set(sbq_desc, mapaddr, map);
- pci_unmap_len_set(sbq_desc, maplen, rx_ring->sbq_buf_size / 2);
- *sbq_desc->addr = cpu_to_le64(map);
bq++;
}
- return 0;
-mem_err:
- ql_free_sbq_buffers(qdev, rx_ring);
- return -ENOMEM;
}
-
static void ql_free_rx_resources(struct ql_adapter *qdev,
struct rx_ring *rx_ring)
{
- if (rx_ring->sbq_len)
- ql_free_sbq_buffers(qdev, rx_ring);
- if (rx_ring->lbq_len)
- ql_free_lbq_buffers(qdev, rx_ring);
-
/* Free the small buffer queue. */
if (rx_ring->sbq_base) {
pci_free_consistent(qdev->pdev,
@@ -2334,11 +2294,7 @@ static int ql_alloc_rx_resources(struct ql_adapter *qdev,
goto err_mem;
}
- if (ql_alloc_sbq_buffers(qdev, rx_ring)) {
- QPRINTK(qdev, IFUP, ERR,
- "Small buffer allocation failed.\n");
- goto err_mem;
- }
+ ql_init_sbq_ring(qdev, rx_ring);
}
if (rx_ring->lbq_len) {
@@ -2366,14 +2322,7 @@ static int ql_alloc_rx_resources(struct ql_adapter *qdev,
goto err_mem;
}
- /*
- * Allocate the buffers.
- */
- if (ql_alloc_lbq_buffers(qdev, rx_ring)) {
- QPRINTK(qdev, IFUP, ERR,
- "Large buffer allocation failed.\n");
- goto err_mem;
- }
+ ql_init_lbq_ring(qdev, rx_ring);
}
return 0;
@@ -2467,6 +2416,7 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring)
qdev->doorbell_area + (DB_PAGE_SIZE * (128 + rx_ring->cq_id));
int err = 0;
u16 bq_len;
+ u64 tmp;
/* Set up the shadow registers for this ring. */
rx_ring->prod_idx_sh_reg = shadow_reg;
@@ -2512,7 +2462,8 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring)
FLAGS_LI; /* Load irq delay values */
if (rx_ring->lbq_len) {
cqicb->flags |= FLAGS_LL; /* Load lbq values */
- *((u64 *) rx_ring->lbq_base_indirect) = rx_ring->lbq_base_dma;
+ tmp = (u64)rx_ring->lbq_base_dma;;
+ *((__le64 *) rx_ring->lbq_base_indirect) = cpu_to_le64(tmp);
cqicb->lbq_addr =
cpu_to_le64(rx_ring->lbq_base_indirect_dma);
bq_len = (rx_ring->lbq_buf_size == 65536) ? 0 :
@@ -2521,25 +2472,26 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring)
bq_len = (rx_ring->lbq_len == 65536) ? 0 :
(u16) rx_ring->lbq_len;
cqicb->lbq_len = cpu_to_le16(bq_len);
- rx_ring->lbq_prod_idx = rx_ring->lbq_len - 16;
+ rx_ring->lbq_prod_idx = 0;
rx_ring->lbq_curr_idx = 0;
- rx_ring->lbq_clean_idx = rx_ring->lbq_prod_idx;
- rx_ring->lbq_free_cnt = 16;
+ rx_ring->lbq_clean_idx = 0;
+ rx_ring->lbq_free_cnt = rx_ring->lbq_len;
}
if (rx_ring->sbq_len) {
cqicb->flags |= FLAGS_LS; /* Load sbq values */
- *((u64 *) rx_ring->sbq_base_indirect) = rx_ring->sbq_base_dma;
+ tmp = (u64)rx_ring->sbq_base_dma;;
+ *((__le64 *) rx_ring->sbq_base_indirect) = cpu_to_le64(tmp);
cqicb->sbq_addr =
cpu_to_le64(rx_ring->sbq_base_indirect_dma);
cqicb->sbq_buf_size =
- cpu_to_le16(((rx_ring->sbq_buf_size / 2) + 8) & 0xfffffff8);
+ cpu_to_le16((u16)(rx_ring->sbq_buf_size/2));
bq_len = (rx_ring->sbq_len == 65536) ? 0 :
(u16) rx_ring->sbq_len;
cqicb->sbq_len = cpu_to_le16(bq_len);
- rx_ring->sbq_prod_idx = rx_ring->sbq_len - 16;
+ rx_ring->sbq_prod_idx = 0;
rx_ring->sbq_curr_idx = 0;
- rx_ring->sbq_clean_idx = rx_ring->sbq_prod_idx;
- rx_ring->sbq_free_cnt = 16;
+ rx_ring->sbq_clean_idx = 0;
+ rx_ring->sbq_free_cnt = rx_ring->sbq_len;
}
switch (rx_ring->type) {
case TX_Q:
@@ -2592,17 +2544,6 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring)
QPRINTK(qdev, IFUP, ERR, "Failed to load CQICB.\n");
return err;
}
- QPRINTK(qdev, IFUP, INFO, "Successfully loaded CQICB.\n");
- /*
- * Advance the producer index for the buffer queues.
- */
- wmb();
- if (rx_ring->lbq_len)
- ql_write_db_reg(rx_ring->lbq_prod_idx,
- rx_ring->lbq_prod_idx_db_reg);
- if (rx_ring->sbq_len)
- ql_write_db_reg(rx_ring->sbq_prod_idx,
- rx_ring->sbq_prod_idx_db_reg);
return err;
}
@@ -3183,7 +3124,7 @@ static int ql_adapter_down(struct ql_adapter *qdev)
ql_disable_interrupts(qdev);
ql_tx_ring_clean(qdev);
-
+ ql_free_rx_buffers(qdev);
status = ql_adapter_reset(qdev);
if (status)
QPRINTK(qdev, IFDOWN, ERR, "reset(func #%d) FAILED!\n",
@@ -3201,6 +3142,7 @@ static int ql_adapter_up(struct ql_adapter *qdev)
goto err_init;
}
set_bit(QL_ADAPTER_UP, &qdev->flags);
+ ql_alloc_rx_buffers(qdev);
ql_enable_all_completion_interrupts(qdev);
if ((ql_read32(qdev, STS) & qdev->port_init))
ql_link_on(qdev);
--
1.6.0.2
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 11/21] [next] qlge: Cleanup spin lock usage for some register accesses.
2009-01-23 15:15 [PATCH 0/21][next] qlge: Clean up and add firmware support Ron Mercer
` (9 preceding siblings ...)
2009-01-23 15:16 ` [PATCH 10/21] [next] qlge: Cleanup rx buffer allocations Ron Mercer
@ 2009-01-23 15:16 ` Ron Mercer
2009-01-23 15:16 ` [PATCH 12/21] [next] qlge: Clean up chip reset path Ron Mercer
` (10 subsequent siblings)
21 siblings, 0 replies; 28+ messages in thread
From: Ron Mercer @ 2009-01-23 15:16 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-driver, ron.mercer
Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
---
drivers/net/qlge/qlge_main.c | 37 +++++++++++++++++++------------------
1 files changed, 19 insertions(+), 18 deletions(-)
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index 55c0f91..176d7e2 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -604,7 +604,6 @@ u32 ql_enable_completion_interrupt(struct ql_adapter *qdev, u32 intr)
static u32 ql_disable_completion_interrupt(struct ql_adapter *qdev, u32 intr)
{
u32 var = 0;
- unsigned long hw_flags;
struct intr_context *ctx;
/* HW disables for us if we're MSIX multi interrupts and
@@ -614,14 +613,14 @@ static u32 ql_disable_completion_interrupt(struct ql_adapter *qdev, u32 intr)
return 0;
ctx = qdev->intr_context + intr;
- spin_lock_irqsave(&qdev->hw_lock, hw_flags);
+ spin_lock(&qdev->hw_lock);
if (!atomic_read(&ctx->irq_cnt)) {
ql_write32(qdev, INTR_EN,
ctx->intr_dis_mask);
var = ql_read32(qdev, STS);
}
atomic_inc(&ctx->irq_cnt);
- spin_unlock_irqrestore(&qdev->hw_lock, hw_flags);
+ spin_unlock(&qdev->hw_lock);
return var;
}
@@ -1714,16 +1713,17 @@ static void ql_vlan_rx_add_vid(struct net_device *ndev, u16 vid)
struct ql_adapter *qdev = netdev_priv(ndev);
u32 enable_bit = MAC_ADDR_E;
int status;
+ unsigned long hw_flags = 0;
status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
if (status)
return;
- spin_lock(&qdev->hw_lock);
+ spin_lock_irqsave(&qdev->hw_lock, hw_flags);
if (ql_set_mac_addr_reg
(qdev, (u8 *) &enable_bit, MAC_ADDR_TYPE_VLAN, vid)) {
QPRINTK(qdev, IFUP, ERR, "Failed to init vlan address.\n");
}
- spin_unlock(&qdev->hw_lock);
+ spin_unlock_irqrestore(&qdev->hw_lock, hw_flags);
ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
}
@@ -1731,18 +1731,19 @@ static void ql_vlan_rx_kill_vid(struct net_device *ndev, u16 vid)
{
struct ql_adapter *qdev = netdev_priv(ndev);
u32 enable_bit = 0;
+ unsigned long hw_flags = 0;
int status;
status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
if (status)
return;
- spin_lock(&qdev->hw_lock);
+ spin_lock_irqsave(&qdev->hw_lock, hw_flags);
if (ql_set_mac_addr_reg
(qdev, (u8 *) &enable_bit, MAC_ADDR_TYPE_VLAN, vid)) {
QPRINTK(qdev, IFUP, ERR, "Failed to clear vlan address.\n");
}
- spin_unlock(&qdev->hw_lock);
+ spin_unlock_irqrestore(&qdev->hw_lock, hw_flags);
ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
}
@@ -3383,12 +3384,13 @@ static void qlge_set_multicast_list(struct net_device *ndev)
{
struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev);
struct dev_mc_list *mc_ptr;
+ unsigned long hw_flags = 0;
int i, status;
status = ql_sem_spinlock(qdev, SEM_RT_IDX_MASK);
if (status)
return;
- spin_lock(&qdev->hw_lock);
+ spin_lock_irqsave(&qdev->hw_lock, hw_flags);
/*
* Set or clear promiscuous mode if a
* transition is taking place.
@@ -3468,7 +3470,7 @@ static void qlge_set_multicast_list(struct net_device *ndev)
ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
}
exit:
- spin_unlock(&qdev->hw_lock);
+ spin_unlock_irqrestore(&qdev->hw_lock, hw_flags);
ql_sem_unlock(qdev, SEM_RT_IDX_MASK);
}
@@ -3476,7 +3478,8 @@ static int qlge_set_mac_address(struct net_device *ndev, void *p)
{
struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev);
struct sockaddr *addr = p;
- int ret = 0;
+ unsigned long hw_flags = 0;
+ int status;
if (netif_running(ndev))
return -EBUSY;
@@ -3484,16 +3487,14 @@ static int qlge_set_mac_address(struct net_device *ndev, void *p)
if (!is_valid_ether_addr(addr->sa_data))
return -EADDRNOTAVAIL;
memcpy(ndev->dev_addr, addr->sa_data, ndev->addr_len);
-
- spin_lock(&qdev->hw_lock);
- if (ql_set_mac_addr_reg(qdev, (u8 *) ndev->dev_addr,
- MAC_ADDR_TYPE_CAM_MAC, qdev->func)) {/* Unicast */
+ spin_lock_irqsave(&qdev->hw_lock, hw_flags);
+ status = ql_set_mac_addr_reg(qdev, (u8 *) ndev->dev_addr,
+ MAC_ADDR_TYPE_CAM_MAC, qdev->func * MAX_CQ);
+ spin_unlock_irqrestore(&qdev->hw_lock, hw_flags);
+ if (status)
QPRINTK(qdev, HW, ERR, "Failed to load MAC address.\n");
- ret = -1;
- }
- spin_unlock(&qdev->hw_lock);
- return ret;
+ return status;
}
static void qlge_tx_timeout(struct net_device *ndev)
--
1.6.0.2
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 12/21] [next] qlge: Clean up chip reset path.
2009-01-23 15:15 [PATCH 0/21][next] qlge: Clean up and add firmware support Ron Mercer
` (10 preceding siblings ...)
2009-01-23 15:16 ` [PATCH 11/21] [next] qlge: Cleanup spin lock usage for some register accesses Ron Mercer
@ 2009-01-23 15:16 ` Ron Mercer
2009-01-23 15:16 ` [PATCH 13/21] [next] qlge: Cleanup MPI RISC " Ron Mercer
` (9 subsequent siblings)
21 siblings, 0 replies; 28+ messages in thread
From: Ron Mercer @ 2009-01-23 15:16 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-driver, ron.mercer
Get rid of ql_cycle_adapter() as it's small and only called
from one place.
Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
---
drivers/net/qlge/qlge_main.c | 45 ++++++++++++++++++-----------------------
1 files changed, 20 insertions(+), 25 deletions(-)
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index 176d7e2..023dfe9 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -1544,6 +1544,7 @@ void ql_queue_asic_error(struct ql_adapter *qdev)
{
ql_link_off(qdev);
ql_disable_interrupts(qdev);
+ clear_bit(QL_ADAPTER_UP, &qdev->flags);
queue_delayed_work(qdev->workqueue, &qdev->asic_reset_work, 0);
}
@@ -3094,7 +3095,8 @@ static int ql_adapter_down(struct ql_adapter *qdev)
ql_link_off(qdev);
- cancel_delayed_work_sync(&qdev->asic_reset_work);
+ if (test_bit(QL_ADAPTER_UP, &qdev->flags))
+ cancel_delayed_work_sync(&qdev->asic_reset_work);
cancel_delayed_work_sync(&qdev->mpi_reset_work);
cancel_delayed_work_sync(&qdev->mpi_work);
@@ -3154,28 +3156,6 @@ err_init:
return err;
}
-static int ql_cycle_adapter(struct ql_adapter *qdev)
-{
- int status;
-
- status = ql_adapter_down(qdev);
- if (status)
- goto error;
-
- status = ql_adapter_up(qdev);
- if (status)
- goto error;
-
- return status;
-error:
- QPRINTK(qdev, IFUP, ALERT,
- "Driver up/down cycle failed, closing device\n");
- rtnl_lock();
- dev_close(qdev->ndev);
- rtnl_unlock();
- return status;
-}
-
static void ql_release_adapter_resources(struct ql_adapter *qdev)
{
ql_free_mem_resources(qdev);
@@ -3500,14 +3480,29 @@ static int qlge_set_mac_address(struct net_device *ndev, void *p)
static void qlge_tx_timeout(struct net_device *ndev)
{
struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev);
- queue_delayed_work(qdev->workqueue, &qdev->asic_reset_work, 0);
+ ql_queue_asic_error(qdev);
}
static void ql_asic_reset_work(struct work_struct *work)
{
struct ql_adapter *qdev =
container_of(work, struct ql_adapter, asic_reset_work.work);
- ql_cycle_adapter(qdev);
+ int status;
+
+ status = ql_adapter_down(qdev);
+ if (status)
+ goto error;
+ status = ql_adapter_up(qdev);
+ if (status)
+ goto error;
+ return;
+error:
+ QPRINTK(qdev, IFUP, ALERT,
+ "Driver up/down cycle failed, closing device\n");
+ rtnl_lock();
+ set_bit(QL_ADAPTER_UP, &qdev->flags);
+ dev_close(qdev->ndev);
+ rtnl_unlock();
}
static void ql_get_board_info(struct ql_adapter *qdev)
--
1.6.0.2
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 13/21] [next] qlge: Cleanup MPI RISC reset path.
2009-01-23 15:15 [PATCH 0/21][next] qlge: Clean up and add firmware support Ron Mercer
` (11 preceding siblings ...)
2009-01-23 15:16 ` [PATCH 12/21] [next] qlge: Clean up chip reset path Ron Mercer
@ 2009-01-23 15:16 ` Ron Mercer
2009-01-23 15:16 ` [PATCH 14/21] [next] qlge: Clean up MPI firware event handler Ron Mercer
` (8 subsequent siblings)
21 siblings, 0 replies; 28+ messages in thread
From: Ron Mercer @ 2009-01-23 15:16 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-driver, ron.mercer
Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
---
drivers/net/qlge/qlge_mpi.c | 40 +++++++++++++++++++++++++++++++++++-----
1 files changed, 35 insertions(+), 5 deletions(-)
diff --git a/drivers/net/qlge/qlge_mpi.c b/drivers/net/qlge/qlge_mpi.c
index fa31891..eda17b0 100644
--- a/drivers/net/qlge/qlge_mpi.c
+++ b/drivers/net/qlge/qlge_mpi.c
@@ -1,6 +1,6 @@
#include "qlge.h"
-static int ql_read_mbox_reg(struct ql_adapter *qdev, u32 reg, u32 *data)
+static int ql_read_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 *data)
{
int status;
/* wait for reg to come ready */
@@ -19,6 +19,37 @@ exit:
return status;
}
+static int ql_write_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 data)
+{
+ int status = 0;
+ /* wait for reg to come ready */
+ status = ql_wait_reg_rdy(qdev, PROC_ADDR, PROC_ADDR_RDY, PROC_ADDR_ERR);
+ if (status)
+ goto exit;
+ /* write the data to the data reg */
+ ql_write32(qdev, PROC_DATA, data);
+ /* trigger the write */
+ ql_write32(qdev, PROC_ADDR, reg);
+ /* wait for reg to come ready */
+ status = ql_wait_reg_rdy(qdev, PROC_ADDR, PROC_ADDR_RDY, PROC_ADDR_ERR);
+ if (status)
+ goto exit;
+exit:
+ return status;
+}
+
+static int ql_soft_reset_mpi_risc(struct ql_adapter *qdev)
+{
+ int status;
+ status = ql_write_mpi_reg(qdev, 0x00001010, 1);
+ if (status)
+ printk(KERN_ERR
+ "Failed to force Auto-Load/"
+ "Auto-Init, status = 0x%.08x!\n",
+ status);
+ return status;
+}
+
static int ql_get_mb_sts(struct ql_adapter *qdev, struct mbox_params *mbcp)
{
int i, status;
@@ -28,7 +59,7 @@ static int ql_get_mb_sts(struct ql_adapter *qdev, struct mbox_params *mbcp)
return -EBUSY;
for (i = 0; i < mbcp->out_count; i++) {
status =
- ql_read_mbox_reg(qdev, qdev->mailbox_out + i,
+ ql_read_mpi_reg(qdev, qdev->mailbox_out + i,
&mbcp->mbox_out[i]);
if (status) {
QPRINTK(qdev, DRV, ERR, "Failed mailbox read.\n");
@@ -144,7 +175,6 @@ void ql_mpi_reset_work(struct work_struct *work)
container_of(work, struct ql_adapter, mpi_reset_work.work);
QPRINTK(qdev, DRV, ERR,
"Enter, qdev = %p..\n", qdev);
- ql_write32(qdev, CSR, CSR_CMD_SET_RST);
- msleep(50);
- ql_write32(qdev, CSR, CSR_CMD_CLR_RST);
+ cancel_delayed_work_sync(&qdev->mpi_work);
+ ql_soft_reset_mpi_risc(qdev);
}
--
1.6.0.2
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 14/21] [next] qlge: Clean up MPI firware event handler.
2009-01-23 15:15 [PATCH 0/21][next] qlge: Clean up and add firmware support Ron Mercer
` (12 preceding siblings ...)
2009-01-23 15:16 ` [PATCH 13/21] [next] qlge: Cleanup MPI RISC " Ron Mercer
@ 2009-01-23 15:16 ` Ron Mercer
2009-01-23 15:16 ` [PATCH 15/21] [next] qlge: Get rid of local xgmac control Ron Mercer
` (7 subsequent siblings)
21 siblings, 0 replies; 28+ messages in thread
From: Ron Mercer @ 2009-01-23 15:16 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-driver, ron.mercer
Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
---
drivers/net/qlge/qlge.h | 1 +
drivers/net/qlge/qlge_main.c | 2 +-
drivers/net/qlge/qlge_mpi.c | 101 ++++++++++++++++++++++++++----------------
3 files changed, 64 insertions(+), 40 deletions(-)
diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h
index 02c7812..0779f07 100644
--- a/drivers/net/qlge/qlge.h
+++ b/drivers/net/qlge/qlge.h
@@ -1512,6 +1512,7 @@ void ql_queue_asic_error(struct ql_adapter *qdev);
u32 ql_enable_completion_interrupt(struct ql_adapter *qdev, u32 intr);
void ql_set_ethtool_ops(struct net_device *ndev);
int ql_read_xgmac_reg64(struct ql_adapter *qdev, u32 reg, u64 *data);
+int ql_cam_route_initialize(struct ql_adapter *qdev);
#if 1
#define QL_ALL_DUMP
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index 023dfe9..ec01dbf 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -2937,7 +2937,7 @@ exit:
return status;
}
-static int ql_cam_route_initialize(struct ql_adapter *qdev)
+int ql_cam_route_initialize(struct ql_adapter *qdev)
{
int status;
diff --git a/drivers/net/qlge/qlge_mpi.c b/drivers/net/qlge/qlge_mpi.c
index eda17b0..867baca 100644
--- a/drivers/net/qlge/qlge_mpi.c
+++ b/drivers/net/qlge/qlge_mpi.c
@@ -75,7 +75,7 @@ static void ql_link_up(struct ql_adapter *qdev, struct mbox_params *mbcp)
mbcp->out_count = 2;
if (ql_get_mb_sts(qdev, mbcp))
- goto exit;
+ return;
qdev->link_status = mbcp->mbox_out[1];
QPRINTK(qdev, DRV, ERR, "Link Up.\n");
@@ -85,9 +85,6 @@ static void ql_link_up(struct ql_adapter *qdev, struct mbox_params *mbcp)
netif_carrier_on(qdev->ndev);
netif_wake_queue(qdev->ndev);
}
-exit:
- /* Clear the MPI firmware status. */
- ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT);
}
static void ql_link_down(struct ql_adapter *qdev, struct mbox_params *mbcp)
@@ -96,7 +93,7 @@ static void ql_link_down(struct ql_adapter *qdev, struct mbox_params *mbcp)
if (ql_get_mb_sts(qdev, mbcp)) {
QPRINTK(qdev, DRV, ERR, "Firmware did not initialize!\n");
- goto exit;
+ return;
}
if (netif_carrier_ok(qdev->ndev)) {
@@ -106,27 +103,77 @@ static void ql_link_down(struct ql_adapter *qdev, struct mbox_params *mbcp)
}
QPRINTK(qdev, DRV, ERR, "Link Down.\n");
QPRINTK(qdev, DRV, ERR, "Link Status = 0x%.08x.\n", mbcp->mbox_out[1]);
-exit:
- /* Clear the MPI firmware status. */
- ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT);
}
static void ql_init_fw_done(struct ql_adapter *qdev, struct mbox_params *mbcp)
{
+ int status;
+
mbcp->out_count = 2;
if (ql_get_mb_sts(qdev, mbcp)) {
QPRINTK(qdev, DRV, ERR, "Firmware did not initialize!\n");
- goto exit;
+ return;
+ }
+ status = ql_cam_route_initialize(qdev);
+ if (status) {
+ QPRINTK(qdev, IFUP, ERR,
+ "Failed to init CAM/Routing tables.\n");
+ return;
}
QPRINTK(qdev, DRV, ERR, "Firmware initialized!\n");
QPRINTK(qdev, DRV, ERR, "Firmware status = 0x%.08x.\n",
mbcp->mbox_out[0]);
QPRINTK(qdev, DRV, ERR, "Firmware Revision = 0x%.08x.\n",
mbcp->mbox_out[1]);
-exit:
- /* Clear the MPI firmware status. */
+}
+
+/* Process an async event and clear it unless it's an
+ * error condition.
+ * This can get called iteratively from the mpi_work thread
+ * when events arrive via an interrupt.
+ * It also gets called when a mailbox command is polling for
+ * it's completion. */
+static int ql_mpi_handler(struct ql_adapter *qdev, struct mbox_params *mbcp)
+{
+ int status;
+
+ /* Just get mailbox zero for now. */
+ mbcp->out_count = 1;
+ status = ql_get_mb_sts(qdev, mbcp);
+ if (status) {
+ QPRINTK(qdev, DRV, ERR,
+ "Could not read MPI, resetting ASIC!\n");
+ ql_queue_asic_error(qdev);
+ goto end;
+ }
+
+ switch (mbcp->mbox_out[0]) {
+
+ case AEN_LINK_UP:
+ ql_link_up(qdev, mbcp);
+ break;
+
+ case AEN_LINK_DOWN:
+ ql_link_down(qdev, mbcp);
+ break;
+
+ case AEN_FW_INIT_DONE:
+ ql_init_fw_done(qdev, mbcp);
+ break;
+
+ case AEN_FW_INIT_FAIL:
+ case AEN_SYS_ERR:
+ case MB_CMD_STS_ERR:
+ default:
+ ql_queue_fw_error(qdev);
+ QPRINTK(qdev, DRV, ERR,
+ "Unsupported AE %.08x.\n", mbcp->mbox_out[0]);
+ /* Clear the MPI firmware status. */
+ }
+end:
ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT);
+ return status;
}
void ql_mpi_work(struct work_struct *work)
@@ -135,37 +182,13 @@ void ql_mpi_work(struct work_struct *work)
container_of(work, struct ql_adapter, mpi_work.work);
struct mbox_params mbc;
struct mbox_params *mbcp = &mbc;
- mbcp->out_count = 1;
while (ql_read32(qdev, STS) & STS_PI) {
- if (ql_get_mb_sts(qdev, mbcp)) {
- QPRINTK(qdev, DRV, ERR,
- "Could not read MPI, resetting ASIC!\n");
- ql_queue_asic_error(qdev);
- }
-
- switch (mbcp->mbox_out[0]) {
- case AEN_LINK_UP:
- ql_link_up(qdev, mbcp);
- break;
- case AEN_LINK_DOWN:
- ql_link_down(qdev, mbcp);
- break;
- case AEN_FW_INIT_DONE:
- ql_init_fw_done(qdev, mbcp);
- break;
- case MB_CMD_STS_GOOD:
- break;
- case AEN_FW_INIT_FAIL:
- case AEN_SYS_ERR:
- case MB_CMD_STS_ERR:
- ql_queue_fw_error(qdev);
- default:
- /* Clear the MPI firmware status. */
- ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT);
- break;
- }
+ memset(mbcp, 0, sizeof(struct mbox_params));
+ mbcp->out_count = 1;
+ ql_mpi_handler(qdev, mbcp);
}
+
ql_enable_completion_interrupt(qdev, 0);
}
--
1.6.0.2
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 15/21] [next] qlge: Get rid of local xgmac control.
2009-01-23 15:15 [PATCH 0/21][next] qlge: Clean up and add firmware support Ron Mercer
` (13 preceding siblings ...)
2009-01-23 15:16 ` [PATCH 14/21] [next] qlge: Clean up MPI firware event handler Ron Mercer
@ 2009-01-23 15:16 ` Ron Mercer
2009-01-23 15:16 ` [PATCH 16/21] [next] qlge: Add some constants for firmware support Ron Mercer
` (6 subsequent siblings)
21 siblings, 0 replies; 28+ messages in thread
From: Ron Mercer @ 2009-01-23 15:16 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-driver, ron.mercer
It's done by firmware now.
Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
---
drivers/net/qlge/qlge_main.c | 106 ------------------------------------------
1 files changed, 0 insertions(+), 106 deletions(-)
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index ec01dbf..ea9ca3f 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -720,25 +720,6 @@ exit:
* register pair. Each read/write requires us to wait for the ready
* bit before reading/writing the data.
*/
-static int ql_write_xgmac_reg(struct ql_adapter *qdev, u32 reg, u32 data)
-{
- int status;
- /* wait for reg to come ready */
- status = ql_wait_reg_rdy(qdev,
- XGMAC_ADDR, XGMAC_ADDR_RDY, XGMAC_ADDR_XME);
- if (status)
- return status;
- /* write the data to the data reg */
- ql_write32(qdev, XGMAC_DATA, data);
- /* trigger the write */
- ql_write32(qdev, XGMAC_ADDR, reg);
- return status;
-}
-
-/* xgmac register are located behind the xgmac_addr and xgmac_data
- * register pair. Each read/write requires us to wait for the ready
- * bit before reading/writing the data.
- */
int ql_read_xgmac_reg(struct ql_adapter *qdev, u32 reg, u32 *data)
{
int status = 0;
@@ -781,87 +762,6 @@ exit:
return status;
}
-/* Take the MAC Core out of reset.
- * Enable statistics counting.
- * Take the transmitter/receiver out of reset.
- * This functionality may be done in the MPI firmware at a
- * later date.
- */
-static int ql_port_initialize(struct ql_adapter *qdev)
-{
- int status = 0;
- u32 data;
-
- if (ql_sem_trylock(qdev, qdev->xg_sem_mask)) {
- /* Another function has the semaphore, so
- * wait for the port init bit to come ready.
- */
- QPRINTK(qdev, LINK, INFO,
- "Another function has the semaphore, so wait for the port init bit to come ready.\n");
- status = ql_wait_reg_rdy(qdev, STS, qdev->port_init, 0);
- if (status) {
- QPRINTK(qdev, LINK, CRIT,
- "Port initialize timed out.\n");
- }
- return status;
- }
-
- QPRINTK(qdev, LINK, INFO, "Got xgmac semaphore!.\n");
- /* Set the core reset. */
- status = ql_read_xgmac_reg(qdev, GLOBAL_CFG, &data);
- if (status)
- goto end;
- data |= GLOBAL_CFG_RESET;
- status = ql_write_xgmac_reg(qdev, GLOBAL_CFG, data);
- if (status)
- goto end;
-
- /* Clear the core reset and turn on jumbo for receiver. */
- data &= ~GLOBAL_CFG_RESET; /* Clear core reset. */
- data |= GLOBAL_CFG_JUMBO; /* Turn on jumbo. */
- data |= GLOBAL_CFG_TX_STAT_EN;
- data |= GLOBAL_CFG_RX_STAT_EN;
- status = ql_write_xgmac_reg(qdev, GLOBAL_CFG, data);
- if (status)
- goto end;
-
- /* Enable transmitter, and clear it's reset. */
- status = ql_read_xgmac_reg(qdev, TX_CFG, &data);
- if (status)
- goto end;
- data &= ~TX_CFG_RESET; /* Clear the TX MAC reset. */
- data |= TX_CFG_EN; /* Enable the transmitter. */
- status = ql_write_xgmac_reg(qdev, TX_CFG, data);
- if (status)
- goto end;
-
- /* Enable receiver and clear it's reset. */
- status = ql_read_xgmac_reg(qdev, RX_CFG, &data);
- if (status)
- goto end;
- data &= ~RX_CFG_RESET; /* Clear the RX MAC reset. */
- data |= RX_CFG_EN; /* Enable the receiver. */
- status = ql_write_xgmac_reg(qdev, RX_CFG, data);
- if (status)
- goto end;
-
- /* Turn on jumbo. */
- status =
- ql_write_xgmac_reg(qdev, MAC_TX_PARAMS, MAC_TX_PARAMS_JUMBO | (0x2580 << 16));
- if (status)
- goto end;
- status =
- ql_write_xgmac_reg(qdev, MAC_RX_PARAMS, 0x2580);
- if (status)
- goto end;
-
- /* Signal to the world that the port is enabled. */
- ql_write32(qdev, STS, ((qdev->port_init << 16) | qdev->port_init));
-end:
- ql_sem_unlock(qdev, qdev->xg_sem_mask);
- return status;
-}
-
/* Get the next large buffer. */
static struct bq_desc *ql_get_curr_lbuf(struct rx_ring *rx_ring)
{
@@ -3023,12 +2923,6 @@ static int ql_adapter_initialize(struct ql_adapter *qdev)
}
}
- status = ql_port_initialize(qdev);
- if (status) {
- QPRINTK(qdev, IFUP, ERR, "Failed to start port.\n");
- return status;
- }
-
/* Set up the MAC address and frame routing filter. */
status = ql_cam_route_initialize(qdev);
if (status) {
--
1.6.0.2
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 16/21] [next] qlge: Add some constants for firmware support.
2009-01-23 15:15 [PATCH 0/21][next] qlge: Clean up and add firmware support Ron Mercer
` (14 preceding siblings ...)
2009-01-23 15:16 ` [PATCH 15/21] [next] qlge: Get rid of local xgmac control Ron Mercer
@ 2009-01-23 15:16 ` Ron Mercer
2009-01-23 15:16 ` [PATCH 17/21] [next] qlge: Use new link up/down func FW event handler Ron Mercer
` (5 subsequent siblings)
21 siblings, 0 replies; 28+ messages in thread
From: Ron Mercer @ 2009-01-23 15:16 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-driver, ron.mercer
Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
---
drivers/net/qlge/qlge.h | 91 +++++++++++++++++++++++++-------------
drivers/net/qlge/qlge_ethtool.c | 3 +-
2 files changed, 62 insertions(+), 32 deletions(-)
diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h
index 0779f07..96287d9 100644
--- a/drivers/net/qlge/qlge.h
+++ b/drivers/net/qlge/qlge.h
@@ -164,7 +164,7 @@ enum {
CSR_RP = (1 << 10),
CSR_CMD_PARM_SHIFT = 22,
CSR_CMD_NOP = 0x00000000,
- CSR_CMD_SET_RST = 0x1000000,
+ CSR_CMD_SET_RST = 0x10000000,
CSR_CMD_CLR_RST = 0x20000000,
CSR_CMD_SET_PAUSE = 0x30000000,
CSR_CMD_CLR_PAUSE = 0x40000000,
@@ -424,7 +424,7 @@ enum {
RX_SYMBOL_ERR = 0x00000370,
RX_MAC_ERR = 0x00000378,
RX_CTL_PKTS = 0x00000380,
- RX_PAUSE_PKTS = 0x00000384,
+ RX_PAUSE_PKTS = 0x00000388,
RX_64_PKTS = 0x00000390,
RX_65_TO_127_PKTS = 0x00000398,
RX_128_255_PKTS = 0x000003a0,
@@ -442,7 +442,7 @@ enum {
MDIO_PORT = 0x00000440,
MDIO_STATUS = 0x00000450,
- /* XGMAC AUX statistics registers */
+ XGMAC_REGISTER_END = 0x00000740,
};
/*
@@ -733,6 +733,11 @@ enum {
AEN_LINK_DOWN = 0x00008012,
AEN_IDC_CMPLT = 0x00008100,
AEN_IDC_REQ = 0x00008101,
+ AEN_IDC_EXT = 0x00008102,
+ AEN_DCBX_CHG = 0x00008110,
+ AEN_AEN_LOST = 0x00008120,
+ AEN_AEN_SFP_IN = 0x00008130,
+ AEN_AEN_SFP_OUT = 0x00008131,
AEN_FW_INIT_DONE = 0x00008400,
AEN_FW_INIT_FAIL = 0x00008401,
@@ -742,40 +747,48 @@ enum {
MB_CMD_MB_TEST = 0x00000006,
MB_CMD_CSUM_TEST = 0x00000007, /* Verify Checksum */
MB_CMD_ABOUT_FW = 0x00000008,
+ MB_CMD_COPY_RISC_RAM = 0x0000000a,
MB_CMD_LOAD_RISC_RAM = 0x0000000b,
MB_CMD_DUMP_RISC_RAM = 0x0000000c,
MB_CMD_WRITE_RAM = 0x0000000d,
+ MB_CMD_INIT_RISC_RAM = 0x0000000e,
MB_CMD_READ_RAM = 0x0000000f,
MB_CMD_STOP_FW = 0x00000014,
MB_CMD_MAKE_SYS_ERR = 0x0000002a,
+ MB_CMD_WRITE_SFP = 0x00000030,
+ MB_CMD_READ_SFP = 0x00000031,
MB_CMD_INIT_FW = 0x00000060,
- MB_CMD_GET_INIT_CB = 0x00000061,
+ MB_CMD_GET_IFCB = 0x00000061,
MB_CMD_GET_FW_STATE = 0x00000069,
MB_CMD_IDC_REQ = 0x00000100, /* Inter-Driver Communication */
MB_CMD_IDC_ACK = 0x00000101, /* Inter-Driver Communication */
MB_CMD_SET_WOL_MODE = 0x00000110, /* Wake On Lan */
- MB_WOL_DISABLE = 0x00000000,
- MB_WOL_MAGIC_PKT = 0x00000001,
- MB_WOL_FLTR = 0x00000002,
- MB_WOL_UCAST = 0x00000004,
- MB_WOL_MCAST = 0x00000008,
- MB_WOL_BCAST = 0x00000010,
- MB_WOL_LINK_UP = 0x00000020,
- MB_WOL_LINK_DOWN = 0x00000040,
+ MB_WOL_DISABLE = 0,
+ MB_WOL_MAGIC_PKT = (1 << 1),
+ MB_WOL_FLTR = (1 << 2),
+ MB_WOL_UCAST = (1 << 3),
+ MB_WOL_MCAST = (1 << 4),
+ MB_WOL_BCAST = (1 << 5),
+ MB_WOL_LINK_UP = (1 << 6),
+ MB_WOL_LINK_DOWN = (1 << 7),
MB_CMD_SET_WOL_FLTR = 0x00000111, /* Wake On Lan Filter */
MB_CMD_CLEAR_WOL_FLTR = 0x00000112, /* Wake On Lan Filter */
MB_CMD_SET_WOL_MAGIC = 0x00000113, /* Wake On Lan Magic Packet */
MB_CMD_CLEAR_WOL_MAGIC = 0x00000114, /* Wake On Lan Magic Packet */
+ MB_CMD_SET_WOL_IMMED = 0x00000115,
MB_CMD_PORT_RESET = 0x00000120,
MB_CMD_SET_PORT_CFG = 0x00000122,
MB_CMD_GET_PORT_CFG = 0x00000123,
- MB_CMD_SET_ASIC_VOLTS = 0x00000130,
- MB_CMD_GET_SNS_DATA = 0x00000131, /* Temp and Volt Sense data. */
+ MB_CMD_GET_LINK_STS = 0x00000124,
/* Mailbox Command Status. */
MB_CMD_STS_GOOD = 0x00004000, /* Success. */
MB_CMD_STS_INTRMDT = 0x00001000, /* Intermediate Complete. */
+ MB_CMD_STS_INVLD_CMD = 0x00004001, /* Invalid. */
+ MB_CMD_STS_XFC_ERR = 0x00004002, /* Interface Error. */
+ MB_CMD_STS_CSUM_ERR = 0x00004003, /* Csum Error. */
MB_CMD_STS_ERR = 0x00004005, /* Error. */
+ MB_CMD_STS_PARAM_ERR = 0x00004006, /* Parameter Error. */
};
struct mbox_params {
@@ -1337,23 +1350,37 @@ enum {
/* link_status bit definitions */
enum {
- LOOPBACK_MASK = 0x00000700,
- LOOPBACK_PCS = 0x00000100,
- LOOPBACK_HSS = 0x00000200,
- LOOPBACK_EXT = 0x00000300,
- PAUSE_MASK = 0x000000c0,
- PAUSE_STD = 0x00000040,
- PAUSE_PRI = 0x00000080,
- SPEED_MASK = 0x00000038,
- SPEED_100Mb = 0x00000000,
- SPEED_1Gb = 0x00000008,
- SPEED_10Gb = 0x00000010,
- LINK_TYPE_MASK = 0x00000007,
- LINK_TYPE_XFI = 0x00000001,
- LINK_TYPE_XAUI = 0x00000002,
- LINK_TYPE_XFI_BP = 0x00000003,
- LINK_TYPE_XAUI_BP = 0x00000004,
- LINK_TYPE_10GBASET = 0x00000005,
+ STS_LOOPBACK_MASK = 0x00000700,
+ STS_LOOPBACK_PCS = 0x00000100,
+ STS_LOOPBACK_HSS = 0x00000200,
+ STS_LOOPBACK_EXT = 0x00000300,
+ STS_PAUSE_MASK = 0x000000c0,
+ STS_PAUSE_STD = 0x00000040,
+ STS_PAUSE_PRI = 0x00000080,
+ STS_SPEED_MASK = 0x00000038,
+ STS_SPEED_100Mb = 0x00000000,
+ STS_SPEED_1Gb = 0x00000008,
+ STS_SPEED_10Gb = 0x00000010,
+ STS_LINK_TYPE_MASK = 0x00000007,
+ STS_LINK_TYPE_XFI = 0x00000001,
+ STS_LINK_TYPE_XAUI = 0x00000002,
+ STS_LINK_TYPE_XFI_BP = 0x00000003,
+ STS_LINK_TYPE_XAUI_BP = 0x00000004,
+ STS_LINK_TYPE_10GBASET = 0x00000005,
+};
+
+/* link_config bit definitions */
+enum {
+ CFG_JUMBO_FRAME_SIZE = 0x00010000,
+ CFG_PAUSE_MASK = 0x00000060,
+ CFG_PAUSE_STD = 0x00000020,
+ CFG_PAUSE_PRI = 0x00000040,
+ CFG_DCBX = 0x00000010,
+ CFG_LOOPBACK_MASK = 0x00000007,
+ CFG_LOOPBACK_PCS = 0x00000002,
+ CFG_LOOPBACK_HSS = 0x00000004,
+ CFG_LOOPBACK_EXT = 0x00000006,
+ CFG_DEFAULT_MAX_FRAME_SIZE = 0x00002580,
};
/*
@@ -1431,6 +1458,8 @@ struct ql_adapter {
u32 port_link_up;
u32 port_init;
u32 link_status;
+ u32 link_config;
+ u32 max_frame_size;
struct flash_params flash;
diff --git a/drivers/net/qlge/qlge_ethtool.c b/drivers/net/qlge/qlge_ethtool.c
index 9d922e2..b3febaf 100644
--- a/drivers/net/qlge/qlge_ethtool.c
+++ b/drivers/net/qlge/qlge_ethtool.c
@@ -271,7 +271,8 @@ static int ql_get_settings(struct net_device *ndev,
ecmd->advertising = ADVERTISED_10000baseT_Full;
ecmd->autoneg = AUTONEG_ENABLE;
ecmd->transceiver = XCVR_EXTERNAL;
- if ((qdev->link_status & LINK_TYPE_MASK) == LINK_TYPE_10GBASET) {
+ if ((qdev->link_status & STS_LINK_TYPE_MASK) ==
+ STS_LINK_TYPE_10GBASET) {
ecmd->supported |= (SUPPORTED_TP | SUPPORTED_Autoneg);
ecmd->advertising |= (ADVERTISED_TP | ADVERTISED_Autoneg);
ecmd->port = PORT_TP;
--
1.6.0.2
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 17/21] [next] qlge: Use new link up/down func FW event handler.
2009-01-23 15:15 [PATCH 0/21][next] qlge: Clean up and add firmware support Ron Mercer
` (15 preceding siblings ...)
2009-01-23 15:16 ` [PATCH 16/21] [next] qlge: Add some constants for firmware support Ron Mercer
@ 2009-01-23 15:16 ` Ron Mercer
2009-01-23 15:16 ` [PATCH 18/21] [next] qlge: Add new firmware event handlers for SFP Ron Mercer
` (4 subsequent siblings)
21 siblings, 0 replies; 28+ messages in thread
From: Ron Mercer @ 2009-01-23 15:16 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-driver, ron.mercer
Add usage of ql_link_on() and ql_link_off functions for
firmware event handlers.
Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
---
drivers/net/qlge/qlge.h | 2 ++
drivers/net/qlge/qlge_main.c | 4 ++--
drivers/net/qlge/qlge_mpi.c | 23 ++++-------------------
3 files changed, 8 insertions(+), 21 deletions(-)
diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h
index 96287d9..a374981 100644
--- a/drivers/net/qlge/qlge.h
+++ b/drivers/net/qlge/qlge.h
@@ -1542,6 +1542,8 @@ u32 ql_enable_completion_interrupt(struct ql_adapter *qdev, u32 intr);
void ql_set_ethtool_ops(struct net_device *ndev);
int ql_read_xgmac_reg64(struct ql_adapter *qdev, u32 reg, u64 *data);
int ql_cam_route_initialize(struct ql_adapter *qdev);
+void ql_link_on(struct ql_adapter *qdev);
+void ql_link_off(struct ql_adapter *qdev);
#if 1
#define QL_ALL_DUMP
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index ea9ca3f..af4b64b 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -240,7 +240,7 @@ exit:
return status;
}
-static void ql_link_on(struct ql_adapter *qdev)
+void ql_link_on(struct ql_adapter *qdev)
{
if (!netif_carrier_ok(qdev->ndev)) {
QPRINTK(qdev, LINK, INFO, "Link is Up.\n");
@@ -249,7 +249,7 @@ static void ql_link_on(struct ql_adapter *qdev)
}
}
-static void ql_link_off(struct ql_adapter *qdev)
+void ql_link_off(struct ql_adapter *qdev)
{
if (netif_carrier_ok(qdev->ndev)) {
QPRINTK(qdev, LINK, INFO, "Link is Down.\n");
diff --git a/drivers/net/qlge/qlge_mpi.c b/drivers/net/qlge/qlge_mpi.c
index 867baca..fd8cdac 100644
--- a/drivers/net/qlge/qlge_mpi.c
+++ b/drivers/net/qlge/qlge_mpi.c
@@ -78,31 +78,16 @@ static void ql_link_up(struct ql_adapter *qdev, struct mbox_params *mbcp)
return;
qdev->link_status = mbcp->mbox_out[1];
- QPRINTK(qdev, DRV, ERR, "Link Up.\n");
- QPRINTK(qdev, DRV, INFO, "Link Status = 0x%.08x.\n", mbcp->mbox_out[1]);
- if (!netif_carrier_ok(qdev->ndev)) {
- QPRINTK(qdev, LINK, INFO, "Link is Up.\n");
- netif_carrier_on(qdev->ndev);
- netif_wake_queue(qdev->ndev);
- }
+ ql_link_on(qdev);
}
static void ql_link_down(struct ql_adapter *qdev, struct mbox_params *mbcp)
{
mbcp->out_count = 3;
- if (ql_get_mb_sts(qdev, mbcp)) {
- QPRINTK(qdev, DRV, ERR, "Firmware did not initialize!\n");
- return;
- }
-
- if (netif_carrier_ok(qdev->ndev)) {
- QPRINTK(qdev, LINK, INFO, "Link is Down.\n");
- netif_carrier_off(qdev->ndev);
- netif_stop_queue(qdev->ndev);
- }
- QPRINTK(qdev, DRV, ERR, "Link Down.\n");
- QPRINTK(qdev, DRV, ERR, "Link Status = 0x%.08x.\n", mbcp->mbox_out[1]);
+ if (ql_get_mb_sts(qdev, mbcp))
+ QPRINTK(qdev, DRV, ERR, "Failed to get link status!\n");
+ ql_link_off(qdev);
}
static void ql_init_fw_done(struct ql_adapter *qdev, struct mbox_params *mbcp)
--
1.6.0.2
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 18/21] [next] qlge: Add new firmware event handlers for SFP.
2009-01-23 15:15 [PATCH 0/21][next] qlge: Clean up and add firmware support Ron Mercer
` (16 preceding siblings ...)
2009-01-23 15:16 ` [PATCH 17/21] [next] qlge: Use new link up/down func FW event handler Ron Mercer
@ 2009-01-23 15:16 ` Ron Mercer
2009-01-23 15:16 ` [PATCH 19/21] [next] qlge: Set the MAC addr/frame routing after a firmware event Ron Mercer
` (3 subsequent siblings)
21 siblings, 0 replies; 28+ messages in thread
From: Ron Mercer @ 2009-01-23 15:16 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-driver, ron.mercer
Add handler for SFP insertion, SFP removal, and
lost event reporting.
Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
---
drivers/net/qlge/qlge_mpi.c | 63 +++++++++++++++++++++++++++++++++++++++++++
1 files changed, 63 insertions(+), 0 deletions(-)
diff --git a/drivers/net/qlge/qlge_mpi.c b/drivers/net/qlge/qlge_mpi.c
index fd8cdac..e113263 100644
--- a/drivers/net/qlge/qlge_mpi.c
+++ b/drivers/net/qlge/qlge_mpi.c
@@ -90,6 +90,57 @@ static void ql_link_down(struct ql_adapter *qdev, struct mbox_params *mbcp)
ql_link_off(qdev);
}
+static int ql_sfp_in(struct ql_adapter *qdev, struct mbox_params *mbcp)
+{
+ int status;
+
+ mbcp->out_count = 5;
+
+ status = ql_get_mb_sts(qdev, mbcp);
+ if (status)
+ QPRINTK(qdev, DRV, ERR, "SFP in AEN broken!\n");
+ else
+ QPRINTK(qdev, DRV, ERR, "SFP insertion detected.\n");
+
+ return status;
+}
+
+static int ql_sfp_out(struct ql_adapter *qdev, struct mbox_params *mbcp)
+{
+ int status;
+
+ mbcp->out_count = 1;
+
+ status = ql_get_mb_sts(qdev, mbcp);
+ if (status)
+ QPRINTK(qdev, DRV, ERR, "SFP out AEN broken!\n");
+ else
+ QPRINTK(qdev, DRV, ERR, "SFP removal detected.\n");
+
+ return status;
+}
+
+static int ql_aen_lost(struct ql_adapter *qdev, struct mbox_params *mbcp)
+{
+ int status;
+
+ mbcp->out_count = 6;
+
+ status = ql_get_mb_sts(qdev, mbcp);
+ if (status)
+ QPRINTK(qdev, DRV, ERR, "Lost AEN broken!\n");
+ else {
+ int i;
+ QPRINTK(qdev, DRV, ERR, "Lost AEN detected.\n");
+ for (i = 0; i < mbcp->out_count; i++)
+ QPRINTK(qdev, DRV, ERR, "mbox_out[%d] = 0x%.08x.\n",
+ i, mbcp->mbox_out[i]);
+
+ }
+
+ return status;
+}
+
static void ql_init_fw_done(struct ql_adapter *qdev, struct mbox_params *mbcp)
{
int status;
@@ -147,6 +198,18 @@ static int ql_mpi_handler(struct ql_adapter *qdev, struct mbox_params *mbcp)
ql_init_fw_done(qdev, mbcp);
break;
+ case AEN_AEN_SFP_IN:
+ ql_sfp_in(qdev, mbcp);
+ break;
+
+ case AEN_AEN_SFP_OUT:
+ ql_sfp_out(qdev, mbcp);
+ break;
+
+ case AEN_AEN_LOST:
+ ql_aen_lost(qdev, mbcp);
+ break;
+
case AEN_FW_INIT_FAIL:
case AEN_SYS_ERR:
case MB_CMD_STS_ERR:
--
1.6.0.2
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 19/21] [next] qlge: Set the MAC addr/frame routing after a firmware event.
2009-01-23 15:15 [PATCH 0/21][next] qlge: Clean up and add firmware support Ron Mercer
` (17 preceding siblings ...)
2009-01-23 15:16 ` [PATCH 18/21] [next] qlge: Add new firmware event handlers for SFP Ron Mercer
@ 2009-01-23 15:16 ` Ron Mercer
2009-01-23 15:16 ` [PATCH 20/21] [next] qlge: Add mailbox command support Ron Mercer
` (2 subsequent siblings)
21 siblings, 0 replies; 28+ messages in thread
From: Ron Mercer @ 2009-01-23 15:16 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-driver, ron.mercer
After port reset the MAC address and frame route settings are cleared.
This patch caused them to be set when the follow up link event occurs.
Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
---
drivers/net/qlge/qlge.h | 2 ++
drivers/net/qlge/qlge_mpi.c | 14 ++++++++++++++
2 files changed, 16 insertions(+), 0 deletions(-)
mode change 100644 => 100755 drivers/net/qlge/qlge.h
diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h
old mode 100644
new mode 100755
index a374981..2f3ca60
--- a/drivers/net/qlge/qlge.h
+++ b/drivers/net/qlge/qlge.h
@@ -1346,6 +1346,8 @@ enum {
QL_DMA64 = (1 << 5),
QL_PROMISCUOUS = (1 << 6),
QL_ALLMULTI = (1 << 7),
+ QL_PORT_CFG = (1 << 8),
+ QL_CAM_RT_SET = (1 << 9),
};
/* link_status bit definitions */
diff --git a/drivers/net/qlge/qlge_mpi.c b/drivers/net/qlge/qlge_mpi.c
index e113263..4e336ef 100644
--- a/drivers/net/qlge/qlge_mpi.c
+++ b/drivers/net/qlge/qlge_mpi.c
@@ -72,12 +72,26 @@ static int ql_get_mb_sts(struct ql_adapter *qdev, struct mbox_params *mbcp)
static void ql_link_up(struct ql_adapter *qdev, struct mbox_params *mbcp)
{
+ int status = 0;
+
mbcp->out_count = 2;
if (ql_get_mb_sts(qdev, mbcp))
return;
qdev->link_status = mbcp->mbox_out[1];
+ /* If we're coming back from an IDC event
+ * then set up the CAM and frame routing.
+ */
+ if (test_bit(QL_CAM_RT_SET, &qdev->flags)) {
+ status = ql_cam_route_initialize(qdev);
+ if (status)
+ QPRINTK(qdev, IFUP, ERR,
+ "Failed to init CAM/Routing tables.\n");
+ else
+ clear_bit(QL_CAM_RT_SET, &qdev->flags);
+ }
+
ql_link_on(qdev);
}
--
1.6.0.2
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 20/21] [next] qlge: Add mailbox command support.
2009-01-23 15:15 [PATCH 0/21][next] qlge: Clean up and add firmware support Ron Mercer
` (18 preceding siblings ...)
2009-01-23 15:16 ` [PATCH 19/21] [next] qlge: Set the MAC addr/frame routing after a firmware event Ron Mercer
@ 2009-01-23 15:16 ` Ron Mercer
2009-01-23 15:16 ` [PATCH 21/21] [next] qlge: Add port config mailbox command Ron Mercer
2009-01-26 6:17 ` [PATCH 0/21][next] qlge: Clean up and add firmware support David Miller
21 siblings, 0 replies; 28+ messages in thread
From: Ron Mercer @ 2009-01-23 15:16 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-driver, ron.mercer
Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
---
drivers/net/qlge/qlge.h | 4 +
drivers/net/qlge/qlge_main.c | 4 +-
drivers/net/qlge/qlge_mpi.c | 273 +++++++++++++++++++++++++++++++++++++++++-
3 files changed, 279 insertions(+), 2 deletions(-)
mode change 100755 => 100644 drivers/net/qlge/qlge.h
diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h
old mode 100755
new mode 100644
index 2f3ca60..afc9a3b
--- a/drivers/net/qlge/qlge.h
+++ b/drivers/net/qlge/qlge.h
@@ -1425,6 +1425,8 @@ struct ql_adapter {
u32 mailbox_in;
u32 mailbox_out;
+ struct mbox_params idc_mbc;
+ struct mutex mpi_mutex;
int tx_ring_size;
int rx_ring_size;
@@ -1471,6 +1473,7 @@ struct ql_adapter {
struct delayed_work asic_reset_work;
struct delayed_work mpi_reset_work;
struct delayed_work mpi_work;
+ struct delayed_work mpi_idc_work;
};
/*
@@ -1538,6 +1541,7 @@ extern int ql_write_cfg(struct ql_adapter *qdev, void *ptr, int size, u32 bit,
void ql_queue_fw_error(struct ql_adapter *qdev);
void ql_mpi_work(struct work_struct *work);
void ql_mpi_reset_work(struct work_struct *work);
+void ql_mpi_idc_work(struct work_struct *work);
int ql_wait_reg_rdy(struct ql_adapter *qdev, u32 reg, u32 bit, u32 ebit);
void ql_queue_asic_error(struct ql_adapter *qdev);
u32 ql_enable_completion_interrupt(struct ql_adapter *qdev, u32 intr);
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index af4b64b..4110402 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -2993,7 +2993,7 @@ static int ql_adapter_down(struct ql_adapter *qdev)
cancel_delayed_work_sync(&qdev->asic_reset_work);
cancel_delayed_work_sync(&qdev->mpi_reset_work);
cancel_delayed_work_sync(&qdev->mpi_work);
-
+ cancel_delayed_work_sync(&qdev->mpi_idc_work);
/* The default queue at index 0 is always processed in
* a workqueue.
*/
@@ -3549,6 +3549,8 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
INIT_DELAYED_WORK(&qdev->asic_reset_work, ql_asic_reset_work);
INIT_DELAYED_WORK(&qdev->mpi_reset_work, ql_mpi_reset_work);
INIT_DELAYED_WORK(&qdev->mpi_work, ql_mpi_work);
+ INIT_DELAYED_WORK(&qdev->mpi_idc_work, ql_mpi_idc_work);
+ mutex_init(&qdev->mpi_mutex);
if (!cards_found) {
dev_info(&pdev->dev, "%s\n", DRV_STRING);
diff --git a/drivers/net/qlge/qlge_mpi.c b/drivers/net/qlge/qlge_mpi.c
index 4e336ef..f2f77c6 100644
--- a/drivers/net/qlge/qlge_mpi.c
+++ b/drivers/net/qlge/qlge_mpi.c
@@ -1,5 +1,25 @@
#include "qlge.h"
+static void ql_display_mb_sts(struct ql_adapter *qdev,
+ struct mbox_params *mbcp)
+{
+ int i;
+ static char *err_sts[] = {
+ "Command Complete",
+ "Command Not Supported",
+ "Host Interface Error",
+ "Checksum Error",
+ "Unused Completion Status",
+ "Test Failed",
+ "Command Parameter Error"};
+
+ QPRINTK(qdev, DRV, ERR, "%s.\n",
+ err_sts[mbcp->mbox_out[0] & 0x0000000f]);
+ for (i = 0; i < mbcp->out_count; i++)
+ QPRINTK(qdev, DRV, ERR, "mbox_out[%d] = 0x%.08x.\n",
+ i, mbcp->mbox_out[i]);
+}
+
static int ql_read_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 *data)
{
int status;
@@ -70,6 +90,95 @@ static int ql_get_mb_sts(struct ql_adapter *qdev, struct mbox_params *mbcp)
return status;
}
+/*
+ * Returns zero on success.
+ */
+static int ql_wait_mbx_cmd_cmplt(struct ql_adapter *qdev)
+{
+ int count = 50; /* TODO: arbitrary for now. */
+ u32 value;
+
+ do {
+ value = ql_read32(qdev, STS);
+ if (value & STS_PI)
+ return 0;
+ mdelay(UDELAY_DELAY); /* 10ms */
+ if (!(count%10))
+ QPRINTK(qdev, DRV, DEBUG,
+ "Waiting for mailbox command to complete.\n");
+ } while (--count);
+ return -ETIMEDOUT;
+}
+
+/* Caller must hold PROC_ADDR semaphore */
+static int ql_exec_mb_cmd(struct ql_adapter *qdev, struct mbox_params *mbcp)
+{
+ int i, status;
+
+ /*
+ * Make sure there's nothing pending.
+ * This shouldn't happen.
+ */
+ if (ql_read32(qdev, CSR) & CSR_HRI) {
+ QPRINTK(qdev, DRV, ERR,
+ "%s: CSR_HRI bit set in CSR. Should never happen!\n",
+ __func__);
+ return -EIO;
+ }
+
+ status = ql_sem_spinlock(qdev, SEM_PROC_REG_MASK);
+ if (status) {
+ QPRINTK(qdev, DRV, ERR,
+ "%s: Couldn't get PROC_ADDR semaphore.\n", __func__);
+ return status;
+ }
+
+ /*
+ * Fill the outbound mailboxes.
+ */
+ for (i = 0; i < mbcp->in_count; i++) {
+ status = ql_write_mpi_reg(qdev, qdev->mailbox_in + i,
+ mbcp->mbox_in[i]);
+ if (status)
+ goto end;
+ }
+ /*
+ * Wake up the MPI firmware.
+ */
+ ql_write32(qdev, CSR, CSR_CMD_SET_H2R_INT);
+end:
+ ql_sem_unlock(qdev, SEM_PROC_REG_MASK);
+ return status;
+}
+
+/* MPI Async Event handlers. */
+static int ql_idc_req_aen(struct ql_adapter *qdev)
+{
+ int status;
+ struct mbox_params *mbcp = &qdev->idc_mbc;
+
+ QPRINTK(qdev, DRV, ERR, "Enter!\n");
+ /* Get the status data and start up a thread to
+ * handle the request.
+ */
+ mbcp = &qdev->idc_mbc;
+ mbcp->out_count = 4;
+ status = ql_get_mb_sts(qdev, mbcp);
+ if (status) {
+ QPRINTK(qdev, DRV, ERR,
+ "Could not read MPI, resetting ASIC!\n");
+ ql_queue_asic_error(qdev);
+ } else {
+ /* Begin polled mode early so
+ * we don't get another interrupt
+ * when we leave mpi_worker.
+ */
+ ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16));
+ queue_delayed_work(qdev->workqueue, &qdev->mpi_idc_work, 0);
+ }
+ return status;
+}
+
static void ql_link_up(struct ql_adapter *qdev, struct mbox_params *mbcp)
{
int status = 0;
@@ -187,6 +296,7 @@ static void ql_init_fw_done(struct ql_adapter *qdev, struct mbox_params *mbcp)
static int ql_mpi_handler(struct ql_adapter *qdev, struct mbox_params *mbcp)
{
int status;
+ int orig_count = mbcp->out_count;
/* Just get mailbox zero for now. */
mbcp->out_count = 1;
@@ -200,6 +310,27 @@ static int ql_mpi_handler(struct ql_adapter *qdev, struct mbox_params *mbcp)
switch (mbcp->mbox_out[0]) {
+ case MB_CMD_STS_INTRMDT:
+ case MB_CMD_STS_GOOD:
+ case MB_CMD_STS_INVLD_CMD:
+ case MB_CMD_STS_XFC_ERR:
+ case MB_CMD_STS_CSUM_ERR:
+ case MB_CMD_STS_ERR:
+ case MB_CMD_STS_PARAM_ERR:
+ /* We can only get mailbox status if we're polling from an
+ * unfinished command. Get the rest of the status data and
+ * return back to the caller.
+ * We only end up here when we're polling for a mailbox
+ * command completion.
+ */
+ mbcp->out_count = orig_count;
+ status = ql_get_mb_sts(qdev, mbcp);
+ return status;
+
+ case AEN_IDC_REQ:
+ status = ql_idc_req_aen(qdev);
+ break;
+
case AEN_LINK_UP:
ql_link_up(qdev, mbcp);
break;
@@ -226,7 +357,6 @@ static int ql_mpi_handler(struct ql_adapter *qdev, struct mbox_params *mbcp)
case AEN_FW_INIT_FAIL:
case AEN_SYS_ERR:
- case MB_CMD_STS_ERR:
default:
ql_queue_fw_error(qdev);
QPRINTK(qdev, DRV, ERR,
@@ -238,6 +368,145 @@ end:
return status;
}
+static int ql_mailbox_command(struct ql_adapter *qdev, struct mbox_params *mbcp)
+{
+ int status, count;
+
+ mutex_lock(&qdev->mpi_mutex);
+
+ /* Begin polled mode for MPI */
+ ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16));
+
+ /* Load the mailbox registers and wake up MPI RISC. */
+ status = ql_exec_mb_cmd(qdev, mbcp);
+ if (status)
+ goto end;
+
+
+ /* If we're generating a system error, then there's nothing
+ * to wait for.
+ */
+ if (mbcp->mbox_in[0] == MB_CMD_MAKE_SYS_ERR)
+ goto end;
+
+ /* Wait for the command to complete. We loop
+ * here because some AEN might arrive while
+ * we're waiting for the mailbox command to
+ * complete. If more than 5 arrive then we can
+ * assume something is wrong. */
+ count = 5;
+ do {
+ /* Wait for the interrupt to come in. */
+ status = ql_wait_mbx_cmd_cmplt(qdev);
+ if (status) {
+ QPRINTK(qdev, DRV, ERR,
+ "Failed ql_wait_mbx_cmd_cmplt(),"
+ " status = %d.\n",
+ status);
+ goto end;
+ }
+
+ /* Process the event. If it's an AEN, it
+ * will be handled in-line or a worker
+ * will be spawned. If it's our completion
+ * we will catch it below.
+ */
+ status = ql_mpi_handler(qdev, mbcp);
+ if (status) {
+ QPRINTK(qdev, DRV, ERR,
+ "Failed ql_mpi_hander(), status = %d.\n",
+ status);
+ goto end;
+ }
+
+ /* It's either the completion for our mailbox
+ * command complete or an AEN. If it's our
+ * completion then get out.
+ */
+ if ((mbcp->mbox_out[0] & 0x0000f000) ==
+ 0x00004000)
+ break;
+ } while (--count);
+
+ if (!count) {
+ QPRINTK(qdev, DRV, ERR,
+ "Timed out waiting for mailbox complet.\n");
+ status = -ETIMEDOUT;
+ goto end;
+ }
+
+ /* Now we can clear the interrupt condition
+ * and look at our status.
+ */
+ ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT);
+
+ if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) {
+ ql_display_mb_sts(qdev, mbcp);
+ status = -EIO;
+ }
+end:
+ mutex_unlock(&qdev->mpi_mutex);
+ /* End polled mode for MPI */
+ ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16) | INTR_MASK_PI);
+ return status;
+}
+int ql_mb_idc_ack(struct ql_adapter *qdev)
+{
+ struct mbox_params mbc;
+ struct mbox_params *mbcp = &mbc;
+ int status = 0;
+
+ memset(mbcp, 0, sizeof(struct mbox_params));
+
+ mbcp->in_count = 5;
+ mbcp->out_count = 1;
+
+ mbcp->mbox_in[0] = MB_CMD_IDC_ACK;
+ mbcp->mbox_in[1] = qdev->idc_mbc.mbox_out[1];
+ mbcp->mbox_in[2] = qdev->idc_mbc.mbox_out[2];
+ mbcp->mbox_in[3] = qdev->idc_mbc.mbox_out[3];
+ mbcp->mbox_in[4] = qdev->idc_mbc.mbox_out[4];
+
+ status = ql_mailbox_command(qdev, mbcp);
+ if (status)
+ return status;
+
+ if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) {
+ QPRINTK(qdev, DRV, ERR,
+ "Failed IDC ACK send.\n");
+ status = -EIO;
+ }
+ return status;
+}
+
+void ql_mpi_idc_work(struct work_struct *work)
+{
+ struct ql_adapter *qdev =
+ container_of(work, struct ql_adapter, mpi_idc_work.work);
+ int status;
+ struct mbox_params *mbcp = &qdev->idc_mbc;
+ u32 aen;
+
+ aen = mbcp->mbox_out[1] >> 16;
+
+ switch (aen) {
+ default:
+ QPRINTK(qdev, DRV, ERR,
+ "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);
+ set_bit(QL_CAM_RT_SET, &qdev->flags);
+ status = ql_mb_idc_ack(qdev);
+ if (status) {
+ QPRINTK(qdev, DRV, ERR,
+ "Bug: No pending IDC!\n");
+ }
+ }
+}
+
void ql_mpi_work(struct work_struct *work)
{
struct ql_adapter *qdev =
@@ -245,12 +514,14 @@ void ql_mpi_work(struct work_struct *work)
struct mbox_params mbc;
struct mbox_params *mbcp = &mbc;
+ mutex_lock(&qdev->mpi_mutex);
while (ql_read32(qdev, STS) & STS_PI) {
memset(mbcp, 0, sizeof(struct mbox_params));
mbcp->out_count = 1;
ql_mpi_handler(qdev, mbcp);
}
+ mutex_unlock(&qdev->mpi_mutex);
ql_enable_completion_interrupt(qdev, 0);
}
--
1.6.0.2
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 21/21] [next] qlge: Add port config mailbox command.
2009-01-23 15:15 [PATCH 0/21][next] qlge: Clean up and add firmware support Ron Mercer
` (19 preceding siblings ...)
2009-01-23 15:16 ` [PATCH 20/21] [next] qlge: Add mailbox command support Ron Mercer
@ 2009-01-23 15:16 ` Ron Mercer
2009-01-26 6:17 ` [PATCH 0/21][next] qlge: Clean up and add firmware support David Miller
21 siblings, 0 replies; 28+ messages in thread
From: Ron Mercer @ 2009-01-23 15:16 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-driver, ron.mercer
Add support for using the port config firmware mailbox command to change
the tx/rx max framesize based on MTU from host.
Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
---
drivers/net/qlge/qlge.h | 3 +
drivers/net/qlge/qlge_main.c | 5 +
drivers/net/qlge/qlge_mpi.c | 198 +++++++++++++++++++++++++++++++++++++++++-
3 files changed, 202 insertions(+), 4 deletions(-)
diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h
index afc9a3b..47e1537 100644
--- a/drivers/net/qlge/qlge.h
+++ b/drivers/net/qlge/qlge.h
@@ -1473,7 +1473,9 @@ struct ql_adapter {
struct delayed_work asic_reset_work;
struct delayed_work mpi_reset_work;
struct delayed_work mpi_work;
+ struct delayed_work mpi_port_cfg_work;
struct delayed_work mpi_idc_work;
+ struct completion ide_completion;
};
/*
@@ -1542,6 +1544,7 @@ void ql_queue_fw_error(struct ql_adapter *qdev);
void ql_mpi_work(struct work_struct *work);
void ql_mpi_reset_work(struct work_struct *work);
void ql_mpi_idc_work(struct work_struct *work);
+void ql_mpi_port_cfg_work(struct work_struct *work);
int ql_wait_reg_rdy(struct ql_adapter *qdev, u32 reg, u32 bit, u32 ebit);
void ql_queue_asic_error(struct ql_adapter *qdev);
u32 ql_enable_completion_interrupt(struct ql_adapter *qdev, u32 intr);
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index 4110402..92189f7 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -2994,6 +2994,7 @@ static int ql_adapter_down(struct ql_adapter *qdev)
cancel_delayed_work_sync(&qdev->mpi_reset_work);
cancel_delayed_work_sync(&qdev->mpi_work);
cancel_delayed_work_sync(&qdev->mpi_idc_work);
+ cancel_delayed_work_sync(&qdev->mpi_port_cfg_work);
/* The default queue at index 0 is always processed in
* a workqueue.
*/
@@ -3236,6 +3237,8 @@ static int qlge_change_mtu(struct net_device *ndev, int new_mtu)
if (ndev->mtu == 1500 && new_mtu == 9000) {
QPRINTK(qdev, IFUP, ERR, "Changing to jumbo MTU.\n");
+ queue_delayed_work(qdev->workqueue,
+ &qdev->mpi_port_cfg_work, 0);
} else if (ndev->mtu == 9000 && new_mtu == 1500) {
QPRINTK(qdev, IFUP, ERR, "Changing to normal MTU.\n");
} else if ((ndev->mtu == 1500 && new_mtu == 1500) ||
@@ -3550,6 +3553,8 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
INIT_DELAYED_WORK(&qdev->mpi_reset_work, ql_mpi_reset_work);
INIT_DELAYED_WORK(&qdev->mpi_work, ql_mpi_work);
INIT_DELAYED_WORK(&qdev->mpi_idc_work, ql_mpi_idc_work);
+ INIT_DELAYED_WORK(&qdev->mpi_port_cfg_work, ql_mpi_port_cfg_work);
+ init_completion(&qdev->ide_completion);
mutex_init(&qdev->mpi_mutex);
if (!cards_found) {
diff --git a/drivers/net/qlge/qlge_mpi.c b/drivers/net/qlge/qlge_mpi.c
index f2f77c6..864df38 100644
--- a/drivers/net/qlge/qlge_mpi.c
+++ b/drivers/net/qlge/qlge_mpi.c
@@ -179,6 +179,27 @@ static int ql_idc_req_aen(struct ql_adapter *qdev)
return status;
}
+static int ql_idc_cmplt_aen(struct ql_adapter *qdev)
+{
+ int status;
+ struct mbox_params *mbcp = &qdev->idc_mbc;
+
+ mbcp->out_count = 4;
+ status = ql_get_mb_sts(qdev, mbcp);
+ if (status) {
+ QPRINTK(qdev, DRV, ERR,
+ "Could not read MPI, resetting RISC!\n");
+ ql_queue_fw_error(qdev);
+ } else
+ /* Wake up the sleeping mpi_idc_work thread that is
+ * waiting for this event.
+ */
+
+ complete(&qdev->ide_completion);
+
+ return status;
+}
+
static void ql_link_up(struct ql_adapter *qdev, struct mbox_params *mbcp)
{
int status = 0;
@@ -331,6 +352,11 @@ static int ql_mpi_handler(struct ql_adapter *qdev, struct mbox_params *mbcp)
status = ql_idc_req_aen(qdev);
break;
+ case AEN_IDC_CMPLT:
+ case AEN_IDC_EXT:
+ status = ql_idc_cmplt_aen(qdev);
+ break;
+
case AEN_LINK_UP:
ql_link_up(qdev, mbcp);
break;
@@ -423,8 +449,10 @@ static int ql_mailbox_command(struct ql_adapter *qdev, struct mbox_params *mbcp)
* command complete or an AEN. If it's our
* completion then get out.
*/
- if ((mbcp->mbox_out[0] & 0x0000f000) ==
- 0x00004000)
+ if (((mbcp->mbox_out[0] & 0x0000f000) ==
+ MB_CMD_STS_GOOD) ||
+ ((mbcp->mbox_out[0] & 0x0000f000) ==
+ MB_CMD_STS_INTRMDT))
break;
} while (--count);
@@ -440,7 +468,10 @@ static int ql_mailbox_command(struct ql_adapter *qdev, struct mbox_params *mbcp)
*/
ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT);
- if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) {
+ if (((mbcp->mbox_out[0] & 0x0000f000) !=
+ MB_CMD_STS_GOOD) &&
+ ((mbcp->mbox_out[0] & 0x0000f000) !=
+ MB_CMD_STS_INTRMDT)) {
ql_display_mb_sts(qdev, mbcp);
status = -EIO;
}
@@ -450,7 +481,8 @@ end:
ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16) | INTR_MASK_PI);
return status;
}
-int ql_mb_idc_ack(struct ql_adapter *qdev)
+
+static int ql_mb_idc_ack(struct ql_adapter *qdev)
{
struct mbox_params mbc;
struct mbox_params *mbcp = &mbc;
@@ -479,6 +511,164 @@ int ql_mb_idc_ack(struct ql_adapter *qdev)
return status;
}
+/* Most likely will block. */
+static int ql_mb_set_port_cfg(struct ql_adapter *qdev)
+{
+ struct mbox_params mbc;
+ struct mbox_params *mbcp = &mbc;
+ int status = 0;
+
+ memset(mbcp, 0, sizeof(struct mbox_params));
+
+ mbcp->in_count = 3;
+ mbcp->out_count = 1;
+
+ mbcp->mbox_in[0] = MB_CMD_SET_PORT_CFG;
+ mbcp->mbox_in[1] = qdev->link_config;
+ mbcp->mbox_in[2] = qdev->max_frame_size;
+
+
+ status = ql_mailbox_command(qdev, mbcp);
+ if (status)
+ return status;
+
+ if (mbcp->mbox_out[0] == MB_CMD_STS_INTRMDT) {
+ QPRINTK(qdev, DRV, ERR,
+ "Port Config sent, wait for IDC.\n");
+ } else if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) {
+ QPRINTK(qdev, DRV, ERR,
+ "Failed Set Port Configuration.\n");
+ status = -EIO;
+ }
+ return status;
+}
+
+static int ql_mb_get_port_cfg(struct ql_adapter *qdev)
+{
+ struct mbox_params mbc;
+ struct mbox_params *mbcp = &mbc;
+ int status = 0;
+
+ memset(mbcp, 0, sizeof(struct mbox_params));
+
+ mbcp->in_count = 1;
+ mbcp->out_count = 3;
+
+ mbcp->mbox_in[0] = MB_CMD_GET_PORT_CFG;
+
+ status = ql_mailbox_command(qdev, mbcp);
+ if (status)
+ return status;
+
+ if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) {
+ QPRINTK(qdev, DRV, ERR,
+ "Failed Get Port Configuration.\n");
+ status = -EIO;
+ } else {
+ QPRINTK(qdev, DRV, ERR,
+ "Passed Get Port Configuration.\n");
+ qdev->link_config = mbcp->mbox_out[1];
+ qdev->max_frame_size = mbcp->mbox_out[2];
+ }
+ return status;
+}
+
+static int ql_idc_wait(struct ql_adapter *qdev)
+{
+ int status = -ETIMEDOUT;
+ long wait_time = 1 * HZ;
+ struct mbox_params *mbcp = &qdev->idc_mbc;
+
+ do {
+ /* Wait here for the command to complete
+ * via the IDC process.
+ */
+ wait_time =
+ wait_for_completion_timeout(&qdev->ide_completion,
+ wait_time);
+ if (!wait_time) {
+ QPRINTK(qdev, DRV, ERR,
+ "IDC Timeout.\n");
+ break;
+ }
+
+ /* Now examine the response from the IDC process.
+ * We might have a good completion or a request for
+ * more wait time.
+ */
+ if (mbcp->mbox_out[0] == AEN_IDC_EXT) {
+ QPRINTK(qdev, DRV, ERR,
+ "IDC Time Extension from function.\n");
+ wait_time += (mbcp->mbox_out[1] >> 8) & 0x0000000f;
+ } else if (mbcp->mbox_out[0] == AEN_IDC_CMPLT) {
+ QPRINTK(qdev, DRV, ERR,
+ "IDC Success.\n");
+ status = 0;
+ break;
+ } else {
+ QPRINTK(qdev, DRV, ERR,
+ "IDC: Invalid State 0x%.04x.\n",
+ mbcp->mbox_out[0]);
+ status = -EIO;
+ break;
+ }
+ } while (wait_time);
+
+ return status;
+}
+
+static int ql_set_port_cfg(struct ql_adapter *qdev)
+{
+ int status;
+
+ status = ql_mb_set_port_cfg(qdev);
+ if (status)
+ return status;
+
+ status = ql_idc_wait(qdev);
+ return status;
+}
+
+/* The following routines are worker threads that process
+ * events that may sleep waiting for completion.
+ */
+void ql_mpi_port_cfg_work(struct work_struct *work)
+{
+ struct ql_adapter *qdev =
+ container_of(work, struct ql_adapter, mpi_port_cfg_work.work);
+ struct net_device *ndev = qdev->ndev;
+ int status;
+
+ status = ql_mb_get_port_cfg(qdev);
+ if (status) {
+ QPRINTK(qdev, DRV, ERR,
+ "Bug: Failed to get port config data.\n");
+ goto err;
+ }
+
+ if (ndev->mtu <= 2500)
+ goto end;
+ else if (qdev->link_config & CFG_JUMBO_FRAME_SIZE &&
+ qdev->max_frame_size ==
+ CFG_DEFAULT_MAX_FRAME_SIZE)
+ goto end;
+
+ qdev->link_config |= CFG_JUMBO_FRAME_SIZE;
+ qdev->max_frame_size = CFG_DEFAULT_MAX_FRAME_SIZE;
+ status = ql_set_port_cfg(qdev);
+ if (status) {
+ QPRINTK(qdev, DRV, ERR,
+ "Bug: Failed to set port config data.\n");
+ goto err;
+ }
+end:
+ clear_bit(QL_PORT_CFG, &qdev->flags);
+ return;
+err:
+ ql_queue_fw_error(qdev);
+ goto end;
+}
+
void ql_mpi_idc_work(struct work_struct *work)
{
struct ql_adapter *qdev =
--
1.6.0.2
^ permalink raw reply related [flat|nested] 28+ messages in thread
* Re: [PATCH 02/21] [next] qlge: Add new functions for signaling link up/down.
2009-01-23 15:16 ` [PATCH 02/21] [next] qlge: Add new functions for signaling link up/down Ron Mercer
@ 2009-01-23 23:23 ` Ben Hutchings
2009-01-24 19:32 ` Ron Mercer
0 siblings, 1 reply; 28+ messages in thread
From: Ben Hutchings @ 2009-01-23 23:23 UTC (permalink / raw)
To: Ron Mercer; +Cc: davem, netdev, linux-driver
On Fri, 2009-01-23 at 07:16 -0800, Ron Mercer wrote:
> Centralize this call as it will also be used by firmware events.
>
> Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
> ---
> drivers/net/qlge/qlge_main.c | 38 ++++++++++++++++++++++++--------------
> 1 files changed, 24 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
> index a530f5b..e6f9146 100644
> --- a/drivers/net/qlge/qlge_main.c
> +++ b/drivers/net/qlge/qlge_main.c
> @@ -240,6 +240,24 @@ exit:
> return status;
> }
>
> +static void ql_link_on(struct ql_adapter *qdev)
> +{
> + if (!netif_carrier_ok(qdev->ndev)) {
> + QPRINTK(qdev, LINK, INFO, "Link is Up.\n");
> + netif_carrier_on(qdev->ndev);
> + netif_wake_queue(qdev->ndev);
> + }
> +}
> +
> +static void ql_link_off(struct ql_adapter *qdev)
> +{
> + if (netif_carrier_ok(qdev->ndev)) {
> + QPRINTK(qdev, LINK, INFO, "Link is Down.\n");
> + netif_carrier_off(qdev->ndev);
> + netif_stop_queue(qdev->ndev);
> + }
> +}
> +
netif_{wake,stop_queue}() are redundant with netif_carrier_{on,off}() so
I think this patch is (mostly?) unnecessary.
Ben.
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH 01/21] [next] qlge: Change to device ID 8000 and corresponding flash access.
2009-01-23 15:16 ` [PATCH 01/21] [next] qlge: Change to device ID 8000 and corresponding flash access Ron Mercer
@ 2009-01-23 23:28 ` Ben Hutchings
2009-01-24 19:29 ` Ron Mercer
0 siblings, 1 reply; 28+ messages in thread
From: Ben Hutchings @ 2009-01-23 23:28 UTC (permalink / raw)
To: Ron Mercer; +Cc: davem, netdev, linux-driver
On Fri, 2009-01-23 at 07:16 -0800, Ron Mercer wrote:
[...]
> diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
> index 16eb9dd..a530f5b 100644
> --- a/drivers/net/qlge/qlge_main.c
> +++ b/drivers/net/qlge/qlge_main.c
[...]
> @@ -657,28 +680,38 @@ static int ql_read_flash_word(struct ql_adapter *qdev, int offset, u32 *data)
> if (status)
> goto exit;
> /* get the data */
> - *data = ql_read32(qdev, FLASH_DATA);
> + *data = cpu_to_le32(ql_read32(qdev, FLASH_DATA));
[...]
Should be le32_to_cpu not cpu_to_le32.
Ben.
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH 01/21] [next] qlge: Change to device ID 8000 and corresponding flash access.
2009-01-23 23:28 ` Ben Hutchings
@ 2009-01-24 19:29 ` Ron Mercer
2009-01-25 1:45 ` Ben Hutchings
0 siblings, 1 reply; 28+ messages in thread
From: Ron Mercer @ 2009-01-24 19:29 UTC (permalink / raw)
To: Ben Hutchings; +Cc: davem@davemloft.net, netdev@vger.kernel.org
On Fri, Jan 23, 2009 at 03:28:59PM -0800, Ben Hutchings wrote:
> On Fri, 2009-01-23 at 07:16 -0800, Ron Mercer wrote:
> [...]
> > diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
> > index 16eb9dd..a530f5b 100644
> > --- a/drivers/net/qlge/qlge_main.c
> > +++ b/drivers/net/qlge/qlge_main.c
> [...]
> > @@ -657,28 +680,38 @@ static int ql_read_flash_word(struct ql_adapter *qdev, int offset, u32 *data)
> > if (status)
> > goto exit;
> > /* get the data */
> > - *data = ql_read32(qdev, FLASH_DATA);
> > + *data = cpu_to_le32(ql_read32(qdev, FLASH_DATA));
> [...]
>
> Should be le32_to_cpu not cpu_to_le32.
>
> Ben.
Ben,
The flash_param is stored in flash as an array of __le32 elements. I tried this a number
of ways and what I came up with is the only combination (I could find)
that didn't generate compile or sparse warnings and that works on big
and little endian machines.
You'll note that I've defined the flash_param using little endian.
If I use cpu_to_le32 it would work fine but will produce sparse
warnings.
Would it be acceptable if I used a better comment about that I'm doing?
Ron
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH 02/21] [next] qlge: Add new functions for signaling link up/down.
2009-01-23 23:23 ` Ben Hutchings
@ 2009-01-24 19:32 ` Ron Mercer
0 siblings, 0 replies; 28+ messages in thread
From: Ron Mercer @ 2009-01-24 19:32 UTC (permalink / raw)
To: Ben Hutchings; +Cc: davem@davemloft.net, netdev@vger.kernel.org, Linux Driver
On Fri, Jan 23, 2009 at 03:23:33PM -0800, Ben Hutchings wrote:
> On Fri, 2009-01-23 at 07:16 -0800, Ron Mercer wrote:
> > Centralize this call as it will also be used by firmware events.
> >
> > Signed-off-by: Ron Mercer <ron.mercer@qlogic.com>
> > ---
> > drivers/net/qlge/qlge_main.c | 38 ++++++++++++++++++++++++--------------
> > 1 files changed, 24 insertions(+), 14 deletions(-)
> >
> > diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
> > index a530f5b..e6f9146 100644
> > --- a/drivers/net/qlge/qlge_main.c
> > +++ b/drivers/net/qlge/qlge_main.c
> > @@ -240,6 +240,24 @@ exit:
> > return status;
> > }
> >
> > +static void ql_link_on(struct ql_adapter *qdev)
> > +{
> > + if (!netif_carrier_ok(qdev->ndev)) {
> > + QPRINTK(qdev, LINK, INFO, "Link is Up.\n");
> > + netif_carrier_on(qdev->ndev);
> > + netif_wake_queue(qdev->ndev);
> > + }
> > +}
> > +
> > +static void ql_link_off(struct ql_adapter *qdev)
> > +{
> > + if (netif_carrier_ok(qdev->ndev)) {
> > + QPRINTK(qdev, LINK, INFO, "Link is Down.\n");
> > + netif_carrier_off(qdev->ndev);
> > + netif_stop_queue(qdev->ndev);
> > + }
> > +}
> > +
>
> netif_{wake,stop_queue}() are redundant with netif_carrier_{on,off}() so
> I think this patch is (mostly?) unnecessary.
>
> Ben.
>
> --
> Ben Hutchings, Senior Software Engineer, Solarflare Communications
> Not speaking for my employer; that's the marketing department's job.
> They asked us to note that Solarflare product names are trademarked.
Yes, I see that some of the other drivers got rid of the
start/stop/wake. If I have to re-submit this patch series I will remove
those lines. If Dave accepts these patches then I will remove the lines
in my next series.
Thanks,
Ron
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH 01/21] [next] qlge: Change to device ID 8000 and corresponding flash access.
2009-01-24 19:29 ` Ron Mercer
@ 2009-01-25 1:45 ` Ben Hutchings
0 siblings, 0 replies; 28+ messages in thread
From: Ben Hutchings @ 2009-01-25 1:45 UTC (permalink / raw)
To: Ron Mercer; +Cc: davem@davemloft.net, netdev@vger.kernel.org
On Sat, 2009-01-24 at 11:29 -0800, Ron Mercer wrote:
> On Fri, Jan 23, 2009 at 03:28:59PM -0800, Ben Hutchings wrote:
> > On Fri, 2009-01-23 at 07:16 -0800, Ron Mercer wrote:
> > [...]
> > > diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
> > > index 16eb9dd..a530f5b 100644
> > > --- a/drivers/net/qlge/qlge_main.c
> > > +++ b/drivers/net/qlge/qlge_main.c
> > [...]
> > > @@ -657,28 +680,38 @@ static int ql_read_flash_word(struct ql_adapter *qdev, int offset, u32 *data)
> > > if (status)
> > > goto exit;
> > > /* get the data */
> > > - *data = ql_read32(qdev, FLASH_DATA);
> > > + *data = cpu_to_le32(ql_read32(qdev, FLASH_DATA));
> > [...]
> >
> > Should be le32_to_cpu not cpu_to_le32.
> >
> > Ben.
>
> Ben,
> The flash_param is stored in flash as an array of __le32 elements. I tried this a number
> of ways and what I came up with is the only combination (I could find)
> that didn't generate compile or sparse warnings and that works on big
> and little endian machines.
> You'll note that I've defined the flash_param using little endian.
But the type of *data is u32, not __le32.
> If I use cpu_to_le32 it would work fine but will produce sparse
> warnings.
> Would it be acceptable if I used a better comment about that I'm doing?
OK, cpu_to_le32() is right but the parameter type should be __le32 *
(and ql_get_flash_params() should be consistent with that).
Ben.
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH 0/21][next] qlge: Clean up and add firmware support.
2009-01-23 15:15 [PATCH 0/21][next] qlge: Clean up and add firmware support Ron Mercer
` (20 preceding siblings ...)
2009-01-23 15:16 ` [PATCH 21/21] [next] qlge: Add port config mailbox command Ron Mercer
@ 2009-01-26 6:17 ` David Miller
21 siblings, 0 replies; 28+ messages in thread
From: David Miller @ 2009-01-26 6:17 UTC (permalink / raw)
To: ron.mercer; +Cc: netdev
From: Ron Mercer <ron.mercer@qlogic.com>
Date: Fri, 23 Jan 2009 07:15:13 -0800
> 1) Adds in device ID 8000. Note that it replaces 8012. We don't want to
> carry forward 8012 support unless forced to. If necessary we'll add it
> in disto. It was an early device that didn't have firmware support and
> different flash layout.
You can't add a driver for a device and then say later:
"Oh well, we don't feel like supporting that any longer"
And yes that even applies for something added as recently as September
2008 as this one was.
This leaves a very bad taste in my mouth and that's just the first
patch in the series :-/
You had other changes in the feedback given to you so please undo this
drop of 0x8000 support and respin the rest of the patches too.
I'm completely dropping this series.
^ permalink raw reply [flat|nested] 28+ messages in thread
end of thread, other threads:[~2009-01-26 6:17 UTC | newest]
Thread overview: 28+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-01-23 15:15 [PATCH 0/21][next] qlge: Clean up and add firmware support Ron Mercer
2009-01-23 15:16 ` [PATCH 01/21] [next] qlge: Change to device ID 8000 and corresponding flash access Ron Mercer
2009-01-23 23:28 ` Ben Hutchings
2009-01-24 19:29 ` Ron Mercer
2009-01-25 1:45 ` Ben Hutchings
2009-01-23 15:16 ` [PATCH 02/21] [next] qlge: Add new functions for signaling link up/down Ron Mercer
2009-01-23 23:23 ` Ben Hutchings
2009-01-24 19:32 ` Ron Mercer
2009-01-23 15:16 ` [PATCH 03/21] [next] qlge: Clean and optimize rx buf queue refill Ron Mercer
2009-01-23 15:16 ` [PATCH 04/21] [next] qlge: Clean up adapter reset function Ron Mercer
2009-01-23 15:16 ` [PATCH 05/21] [next] qlge: Add new function for MAC address and frame routing Ron Mercer
2009-01-23 15:16 ` [PATCH 06/21] [next] qlge: Expand granularity on holding hardware semaphore Ron Mercer
2009-01-23 15:16 ` [PATCH 07/21] [next] qlge: Remove lock protection in adapter up/down Ron Mercer
2009-01-23 15:16 ` [PATCH 08/21] [next] qlge: Move interrupt enable to end of adapter up function Ron Mercer
2009-01-23 15:16 ` [PATCH 09/21] [next] qlge: Upgrade print priority for hardware event handler Ron Mercer
2009-01-23 15:16 ` [PATCH 10/21] [next] qlge: Cleanup rx buffer allocations Ron Mercer
2009-01-23 15:16 ` [PATCH 11/21] [next] qlge: Cleanup spin lock usage for some register accesses Ron Mercer
2009-01-23 15:16 ` [PATCH 12/21] [next] qlge: Clean up chip reset path Ron Mercer
2009-01-23 15:16 ` [PATCH 13/21] [next] qlge: Cleanup MPI RISC " Ron Mercer
2009-01-23 15:16 ` [PATCH 14/21] [next] qlge: Clean up MPI firware event handler Ron Mercer
2009-01-23 15:16 ` [PATCH 15/21] [next] qlge: Get rid of local xgmac control Ron Mercer
2009-01-23 15:16 ` [PATCH 16/21] [next] qlge: Add some constants for firmware support Ron Mercer
2009-01-23 15:16 ` [PATCH 17/21] [next] qlge: Use new link up/down func FW event handler Ron Mercer
2009-01-23 15:16 ` [PATCH 18/21] [next] qlge: Add new firmware event handlers for SFP Ron Mercer
2009-01-23 15:16 ` [PATCH 19/21] [next] qlge: Set the MAC addr/frame routing after a firmware event Ron Mercer
2009-01-23 15:16 ` [PATCH 20/21] [next] qlge: Add mailbox command support Ron Mercer
2009-01-23 15:16 ` [PATCH 21/21] [next] qlge: Add port config mailbox command Ron Mercer
2009-01-26 6:17 ` [PATCH 0/21][next] qlge: Clean up and add firmware support David Miller
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).