Skip to content

Commit

Permalink
RESEND [PATCH 3/3] NetXen: Graceful teardown of interface and hardwar…
Browse files Browse the repository at this point in the history
…e upon module unload

Resending patch 3/3 only.

These changes allow driver close routine to be called during module unload,
to clean-up buffers and other software resources, flush queues etc. Also,
hardware is reset to pristine state.

Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
Signed-off-by: Milan Bag <mbag@netxen.com>
Signed-off-by: Wen Xiong <wenxiong@us.ibm.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
  • Loading branch information
Dhananjay Phadke authored and Jeff Garzik committed Jul 2, 2007
1 parent d14e37e commit 96acb6e
Show file tree
Hide file tree
Showing 5 changed files with 210 additions and 76 deletions.
78 changes: 76 additions & 2 deletions drivers/net/netxen/netxen_nic.h
Original file line number Diff line number Diff line change
Expand Up @@ -952,6 +952,24 @@ struct netxen_adapter {
int (*stop_port) (struct netxen_adapter *);
}; /* netxen_adapter structure */

/*
* NetXen dma watchdog control structure
*
* Bit 0 : enabled => R/O: 1 watchdog active, 0 inactive
* Bit 1 : disable_request => 1 req disable dma watchdog
* Bit 2 : enable_request => 1 req enable dma watchdog
* Bit 3-31 : unused
*/

#define netxen_set_dma_watchdog_disable_req(config_word) \
_netxen_set_bits(config_word, 1, 1, 1)
#define netxen_set_dma_watchdog_enable_req(config_word) \
_netxen_set_bits(config_word, 2, 1, 1)
#define netxen_get_dma_watchdog_enabled(config_word) \
((config_word) & 0x1)
#define netxen_get_dma_watchdog_disabled(config_word) \
(((config_word) >> 1) & 0x1)

/* Max number of xmit producer threads that can run simultaneously */
#define MAX_XMIT_PRODUCERS 16

Expand Down Expand Up @@ -1031,8 +1049,8 @@ int netxen_nic_erase_pxe(struct netxen_adapter *adapter);
/* Functions from netxen_nic_init.c */
void netxen_free_adapter_offload(struct netxen_adapter *adapter);
int netxen_initialize_adapter_offload(struct netxen_adapter *adapter);
void netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val);
void netxen_load_firmware(struct netxen_adapter *adapter);
int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val);
int netxen_load_firmware(struct netxen_adapter *adapter);
int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose);
int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp);
int netxen_rom_fast_read_words(struct netxen_adapter *adapter, int addr,
Expand Down Expand Up @@ -1234,6 +1252,62 @@ static inline void get_brd_name_by_type(u32 type, char *name)
name = "Unknown";
}

static inline int
dma_watchdog_shutdown_request(struct netxen_adapter *adapter)
{
u32 ctrl;

/* check if already inactive */
if (netxen_nic_hw_read_wx(adapter,
NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), &ctrl, 4))
printk(KERN_ERR "failed to read dma watchdog status\n");

if (netxen_get_dma_watchdog_enabled(ctrl) == 0)
return 1;

/* Send the disable request */
netxen_set_dma_watchdog_disable_req(ctrl);
netxen_crb_writelit_adapter(adapter,
NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), ctrl);

return 0;
}

static inline int
dma_watchdog_shutdown_poll_result(struct netxen_adapter *adapter)
{
u32 ctrl;

if (netxen_nic_hw_read_wx(adapter,
NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), &ctrl, 4))
printk(KERN_ERR "failed to read dma watchdog status\n");

return ((netxen_get_dma_watchdog_enabled(ctrl) == 0) &&
(netxen_get_dma_watchdog_disabled(ctrl) == 0));
}

static inline int
dma_watchdog_wakeup(struct netxen_adapter *adapter)
{
u32 ctrl;

if (netxen_nic_hw_read_wx(adapter,
NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), &ctrl, 4))
printk(KERN_ERR "failed to read dma watchdog status\n");

if (netxen_get_dma_watchdog_enabled(ctrl))
return 1;

/* send the wakeup request */
netxen_set_dma_watchdog_enable_req(ctrl);

netxen_crb_writelit_adapter(adapter,
NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), ctrl);

return 0;
}


int netxen_is_flash_supported(struct netxen_adapter *adapter);
int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, u64 mac[]);
extern void netxen_change_ringparam(struct netxen_adapter *adapter);
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/netxen/netxen_nic_hdr.h
Original file line number Diff line number Diff line change
Expand Up @@ -687,4 +687,6 @@ enum {

#define PCIE_MAX_MASTER_SPLIT (0x14048)

#define NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL (0x14)

#endif /* __NETXEN_NIC_HDR_H_ */
29 changes: 19 additions & 10 deletions drivers/net/netxen/netxen_nic_hw.c
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter)
recv_crb_registers[ctx].
crb_rcvpeg_state));
while (state != PHAN_PEG_RCV_INITIALIZED && loops < 20) {
udelay(100);
msleep(1);
/* Window 1 call */
state = readl(NETXEN_CRB_NORMALIZE(adapter,
recv_crb_registers
Expand All @@ -394,7 +394,7 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter)
}
adapter->intr_scheme = readl(
NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_CAPABILITIES_FW));
printk(KERN_NOTICE "%s: FW capabilities:0x%x\n", netdev->name,
printk(KERN_NOTICE "%s: FW capabilities:0x%x\n", netxen_nic_driver_name,
adapter->intr_scheme);
DPRINTK(INFO, "Receive Peg ready too. starting stuff\n");

Expand Down Expand Up @@ -701,7 +701,7 @@ void netxen_nic_pci_change_crbwindow(struct netxen_adapter *adapter, u32 wndw)
adapter->curr_window = 0;
}

void netxen_load_firmware(struct netxen_adapter *adapter)
int netxen_load_firmware(struct netxen_adapter *adapter)
{
int i;
u32 data, size = 0;
Expand All @@ -713,15 +713,24 @@ void netxen_load_firmware(struct netxen_adapter *adapter)
writel(1, NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_CAS_RST));

for (i = 0; i < size; i++) {
if (netxen_rom_fast_read(adapter, flashaddr, (int *)&data) != 0) {
DPRINTK(ERR,
"Error in netxen_rom_fast_read(). Will skip"
"loading flash image\n");
return;
}
int retries = 10;
if (netxen_rom_fast_read(adapter, flashaddr, (int *)&data) != 0)
return -EIO;

off = netxen_nic_pci_set_window(adapter, memaddr);
addr = pci_base_offset(adapter, off);
writel(data, addr);
do {
if (readl(addr) == data)
break;
msleep(100);
writel(data, addr);
} while (--retries);
if (!retries) {
printk(KERN_ERR "%s: firmware load aborted, write failed at 0x%x\n",
netxen_nic_driver_name, memaddr);
return -EIO;
}
flashaddr += 4;
memaddr += 4;
}
Expand All @@ -731,7 +740,7 @@ void netxen_load_firmware(struct netxen_adapter *adapter)
NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_CHIP_CLK_CTRL));
writel(0, NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_CAS_RST));

udelay(100);
return 0;
}

int
Expand Down
49 changes: 27 additions & 22 deletions drivers/net/netxen/netxen_nic_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -407,10 +407,7 @@ static inline int do_rom_fast_write(struct netxen_adapter *adapter, int addr,
static inline int
do_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp)
{
if (jiffies > (last_schedule_time + (8 * HZ))) {
last_schedule_time = jiffies;
schedule();
}
cond_resched();

netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr);
netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3);
Expand Down Expand Up @@ -856,10 +853,10 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
netxen_nic_pci_change_crbwindow(adapter, 1);
}
if (init_delay == 1) {
ssleep(1);
msleep(2000);
init_delay = 0;
}
msleep(1);
msleep(20);
}
kfree(buf);

Expand Down Expand Up @@ -935,10 +932,6 @@ int netxen_initialize_adapter_offload(struct netxen_adapter *adapter)
void netxen_free_adapter_offload(struct netxen_adapter *adapter)
{
if (adapter->dummy_dma.addr) {
writel(0, NETXEN_CRB_NORMALIZE(adapter,
CRB_HOST_DUMMY_BUF_ADDR_HI));
writel(0, NETXEN_CRB_NORMALIZE(adapter,
CRB_HOST_DUMMY_BUF_ADDR_LO));
pci_free_consistent(adapter->ahw.pdev,
NETXEN_HOST_DUMMY_DMA_SIZE,
adapter->dummy_dma.addr,
Expand All @@ -947,25 +940,32 @@ void netxen_free_adapter_offload(struct netxen_adapter *adapter)
}
}

void netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val)
int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val)
{
u32 val = 0;
int loops = 0;
int retries = 30;

if (!pegtune_val) {
val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE));
while (val != PHAN_INITIALIZE_COMPLETE &&
val != PHAN_INITIALIZE_ACK && loops < 200000) {
udelay(100);
schedule();
val =
readl(NETXEN_CRB_NORMALIZE
do {
val = readl(NETXEN_CRB_NORMALIZE
(adapter, CRB_CMDPEG_STATE));
loops++;
pegtune_val = readl(NETXEN_CRB_NORMALIZE
(adapter, NETXEN_ROMUSB_GLB_PEGTUNE_DONE));

if (val == PHAN_INITIALIZE_COMPLETE ||
val == PHAN_INITIALIZE_ACK)
return 0;

msleep(1000);
} while (--retries);
if (!retries) {
printk(KERN_WARNING "netxen_phantom_init: init failed, "
"pegtune_val=%x\n", pegtune_val);
return -1;
}
if (val != PHAN_INITIALIZE_COMPLETE)
printk("WARNING: Initial boot wait loop failed...\n");
}

return 0;
}

int netxen_nic_rx_has_work(struct netxen_adapter *adapter)
Expand Down Expand Up @@ -1122,6 +1122,7 @@ netxen_process_rcv(struct netxen_adapter *adapter, int ctxid,
adapter->stats.csummed++;
skb->ip_summed = CHECKSUM_UNNECESSARY;
}
skb->dev = netdev;
if (desc_ctx == RCV_DESC_LRO_CTXID) {
/* True length was only available on the last pkt */
skb_put(skb, buffer->lro_length);
Expand Down Expand Up @@ -1226,6 +1227,7 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max)
NETXEN_CRB_NORMALIZE(adapter,
recv_crb_registers[adapter->portnum].
crb_rcv_status_consumer));
wmb();
}

return count;
Expand Down Expand Up @@ -1278,11 +1280,13 @@ int netxen_process_cmd_ring(unsigned long data)
if (skb && (cmpxchg(&buffer->skb, skb, 0) == skb)) {
pci_unmap_single(pdev, frag->dma, frag->length,
PCI_DMA_TODEVICE);
frag->dma = 0ULL;
for (i = 1; i < buffer->frag_count; i++) {
DPRINTK(INFO, "getting fragment no %d\n", i);
frag++; /* Get the next frag */
pci_unmap_page(pdev, frag->dma, frag->length,
PCI_DMA_TODEVICE);
frag->dma = 0ULL;
}

adapter->stats.skbfreed++;
Expand Down Expand Up @@ -1448,6 +1452,7 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid)
writel(msg,
DB_NORMALIZE(adapter,
NETXEN_RCV_PRODUCER_OFFSET));
wmb();
}
}
}
Expand Down
Loading

0 comments on commit 96acb6e

Please sign in to comment.