NetXen: 1G/10G Ethernet Driver updates - These fixes take care of driver on machines with >4G memory - Driver cleanup
Signed-off-by: Amit S. Kale <[EMAIL PROTECTED]> Signed-off-by: Don Fry <[EMAIL PROTECTED]> diff -Nupr netdev-2.6/drivers/net/netxen.two/netxen_nic_ethtool.c netdev-2.6/drivers/net/netxen/netxen_nic_ethtool.c --- netdev-2.6/drivers/net/netxen.two/netxen_nic_ethtool.c 2006-11-30 09:40:47.000000000 -0800 +++ netdev-2.6/drivers/net/netxen/netxen_nic_ethtool.c 2006-11-30 09:46:16.000000000 -0800 @@ -6,12 +6,12 @@ * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, @@ -118,7 +118,7 @@ netxen_nic_get_drvinfo(struct net_device u32 fw_minor = 0; u32 fw_build = 0; - strncpy(drvinfo->driver, "netxen_nic", 32); + strncpy(drvinfo->driver, netxen_nic_driver_name, 32); strncpy(drvinfo->version, NETXEN_NIC_LINUX_VERSIONID, 32); fw_major = readl(NETXEN_CRB_NORMALIZE(adapter, NETXEN_FW_VERSION_MAJOR)); @@ -211,7 +211,6 @@ netxen_nic_get_settings(struct net_devic printk("ERROR: Unsupported board model %d\n", (netxen_brdtype_t) boardinfo->board_type); return -EIO; - } return 0; @@ -461,20 +460,22 @@ netxen_nic_get_ringparam(struct net_devi { struct netxen_port *port = netdev_priv(dev); struct netxen_adapter *adapter = port->adapter; - int i, j; + int i; ring->rx_pending = 0; + ring->rx_jumbo_pending = 0; for (i = 0; i < MAX_RCV_CTX; ++i) { - for (j = 0; j < NUM_RCV_DESC_RINGS; j++) - ring->rx_pending += - adapter->recv_ctx[i].rcv_desc[j].rcv_pending; + ring->rx_pending += adapter->recv_ctx[i]. + rcv_desc[RCV_DESC_NORMAL_CTXID].rcv_pending; + ring->rx_jumbo_pending += adapter->recv_ctx[i]. + rcv_desc[RCV_DESC_JUMBO_CTXID].rcv_pending; } ring->rx_max_pending = adapter->max_rx_desc_count; ring->tx_max_pending = adapter->max_tx_desc_count; + ring->rx_jumbo_max_pending = adapter->max_jumbo_rx_desc_count; ring->rx_mini_max_pending = 0; ring->rx_mini_pending = 0; - ring->rx_jumbo_max_pending = 0; ring->rx_jumbo_pending = 0; } diff -Nupr netdev-2.6/drivers/net/netxen.two/netxen_nic.h netdev-2.6/drivers/net/netxen/netxen_nic.h --- netdev-2.6/drivers/net/netxen.two/netxen_nic.h 2006-11-30 09:40:47.000000000 -0800 +++ netdev-2.6/drivers/net/netxen/netxen_nic.h 2006-11-30 09:46:16.000000000 -0800 @@ -6,12 +6,12 @@ * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, @@ -89,8 +89,8 @@ * normalize a 64MB crb address to 32MB PCI window * To use NETXEN_CRB_NORMALIZE, window _must_ be set to 1 */ -#define NETXEN_CRB_NORMAL(reg) \ - (reg) - NETXEN_CRB_PCIX_HOST2 + NETXEN_CRB_PCIX_HOST +#define NETXEN_CRB_NORMAL(reg) \ + ((reg) - NETXEN_CRB_PCIX_HOST2 + NETXEN_CRB_PCIX_HOST) #define NETXEN_CRB_NORMALIZE(adapter, reg) \ pci_base_offset(adapter, NETXEN_CRB_NORMAL(reg)) @@ -164,7 +164,7 @@ enum { #define MAX_CMD_DESCRIPTORS 1024 #define MAX_RCV_DESCRIPTORS 32768 -#define MAX_JUMBO_RCV_DESCRIPTORS 1024 +#define MAX_JUMBO_RCV_DESCRIPTORS 4096 #define MAX_RCVSTATUS_DESCRIPTORS MAX_RCV_DESCRIPTORS #define MAX_JUMBO_RCV_DESC MAX_JUMBO_RCV_DESCRIPTORS #define MAX_RCV_DESC MAX_RCV_DESCRIPTORS @@ -592,6 +592,16 @@ struct netxen_skb_frag { u32 length; }; +/* Bounce buffer index */ +struct bounce_index { + /* Index of a buffer */ + unsigned buffer_index; + /* Offset inside the buffer */ + unsigned buffer_offset; +}; + +#define IS_BOUNCE 0xcafebb + /* Following defines are for the state of the buffers */ #define NETXEN_BUFFER_FREE 0 #define NETXEN_BUFFER_BUSY 1 @@ -611,6 +621,8 @@ struct netxen_cmd_buffer { unsigned long time_stamp; u32 state; u32 no_of_descriptors; + u32 tx_bounce_buff; + struct bounce_index bnext; }; /* In rx_buffer, we do not need multiple fragments as is a single buffer */ @@ -619,6 +631,9 @@ struct netxen_rx_buffer { u64 dma; u16 ref_handle; u16 state; + u32 rx_bounce_buff; + struct bounce_index bnext; + char *bounce_ptr; }; /* Board types */ @@ -703,6 +718,7 @@ struct netxen_recv_context { }; #define NETXEN_NIC_MSI_ENABLED 0x02 +#define NETXEN_DMA_MASK 0xfffffffe struct netxen_drvops; @@ -937,9 +953,7 @@ static inline void netxen_nic_disable_in /* * ISR_INT_MASK: Can be read from window 0 or 1. */ - writel(0x7ff, - (void __iomem - *)(PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK))); + writel(0x7ff, PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK)); } @@ -959,14 +973,12 @@ static inline void netxen_nic_enable_int break; } - writel(mask, - (void __iomem - *)(PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK))); + writel(mask, PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK)); if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { mask = 0xbff; - writel(mask, (void __iomem *) - (PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_TARGET_MASK))); + writel(mask, PCI_OFFSET_SECOND_RANGE(adapter, + ISR_INT_TARGET_MASK)); } } @@ -1040,6 +1052,9 @@ static inline void get_brd_name_by_type( int netxen_is_flash_supported(struct netxen_adapter *adapter); int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, u64 mac[]); +int netxen_get_next_bounce_buffer(struct bounce_index *head, + struct bounce_index *tail, + struct bounce_index *biret, unsigned len); extern void netxen_change_ringparam(struct netxen_adapter *adapter); extern int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, diff -Nupr netdev-2.6/drivers/net/netxen.two/netxen_nic_hw.c netdev-2.6/drivers/net/netxen/netxen_nic_hw.c --- netdev-2.6/drivers/net/netxen.two/netxen_nic_hw.c 2006-11-30 09:40:47.000000000 -0800 +++ netdev-2.6/drivers/net/netxen/netxen_nic_hw.c 2006-11-30 09:46:16.000000000 -0800 @@ -650,7 +650,7 @@ void netxen_nic_reg_write(struct netxen_ addr = NETXEN_CRB_NORMALIZE(adapter, off); DPRINTK(INFO, "writing to base %lx offset %llx addr %p data %x\n", - pci_base(adapter, off), off, addr); + pci_base(adapter, off), off, addr, val); writel(val, addr); } @@ -662,7 +662,7 @@ int netxen_nic_reg_read(struct netxen_ad addr = NETXEN_CRB_NORMALIZE(adapter, off); DPRINTK(INFO, "reading from base %lx offset %llx addr %p\n", - adapter->ahw.pci_base, off, addr); + pci_base(adapter, off), off, addr); val = readl(addr); writel(val, addr); @@ -675,7 +675,7 @@ void netxen_nic_write_w0(struct netxen_a void __iomem *addr; netxen_nic_pci_change_crbwindow(adapter, 0); - addr = (void __iomem *)(pci_base_offset(adapter, index)); + addr = pci_base_offset(adapter, index); writel(value, addr); netxen_nic_pci_change_crbwindow(adapter, 1); } @@ -685,7 +685,7 @@ void netxen_nic_read_w0(struct netxen_ad { void __iomem *addr; - addr = (void __iomem *)(pci_base_offset(adapter, index)); + addr = pci_base_offset(adapter, index); netxen_nic_pci_change_crbwindow(adapter, 0); *value = readl(addr); @@ -865,7 +865,7 @@ netxen_crb_writelit_adapter(struct netxe writel(data, NETXEN_CRB_NORMALIZE(adapter, off)); } else { netxen_nic_pci_change_crbwindow(adapter, 0); - addr = (void __iomem *)(pci_base_offset(adapter, off)); + addr = pci_base_offset(adapter, off); writel(data, addr); netxen_nic_pci_change_crbwindow(adapter, 1); } diff -Nupr netdev-2.6/drivers/net/netxen.two/netxen_nic_hw.h netdev-2.6/drivers/net/netxen/netxen_nic_hw.h --- netdev-2.6/drivers/net/netxen.two/netxen_nic_hw.h 2006-11-30 09:40:47.000000000 -0800 +++ netdev-2.6/drivers/net/netxen/netxen_nic_hw.h 2006-11-30 09:46:16.000000000 -0800 @@ -83,8 +83,8 @@ struct netxen_adapter; #define NETXEN_PCI_MAPSIZE_BYTES (NETXEN_PCI_MAPSIZE << 20) #define NETXEN_NIC_LOCKED_READ_REG(X, Y) \ - addr = pci_base_offset(adapter, (X)); \ - *(u32 *)Y = readl(addr); + addr = pci_base_offset(adapter, X); \ + *(u32 *)Y = readl((void __iomem*) addr); struct netxen_port; void netxen_nic_set_link_parameters(struct netxen_port *port); diff -Nupr netdev-2.6/drivers/net/netxen.two/netxen_nic_init.c netdev-2.6/drivers/net/netxen/netxen_nic_init.c --- netdev-2.6/drivers/net/netxen.two/netxen_nic_init.c 2006-11-30 09:40:47.000000000 -0800 +++ netdev-2.6/drivers/net/netxen/netxen_nic_init.c 2006-11-30 09:47:19.000000000 -0800 @@ -53,6 +53,11 @@ static unsigned int crb_addr_xform[NETXE #define NETXEN_NIC_XDMA_RESET 0x8000ff +extern char *rx_bounce_ptr; +extern struct bounce_index tx_bounce_head, tx_bounce_tail, + rx_bounce_head, rx_bounce_tail; +extern spinlock_t rx_bounce_lock, tx_bounce_lock; + static inline void netxen_nic_locked_write_reg(struct netxen_adapter *adapter, unsigned long off, int *data) @@ -191,8 +196,6 @@ void netxen_initialize_adapter_sw(struct } } } - DPRINTK(INFO, "initialized buffers for %s and %s\n", - "adapter->free_cmd_buf_list", "adapter->free_rxbuf"); } void netxen_initialize_adapter_hw(struct netxen_adapter *adapter) @@ -383,8 +386,8 @@ int netxen_rom_wip_poll(struct netxen_ad return 0; } -static inline int do_rom_fast_write(struct netxen_adapter *adapter, - int addr, int data) +static inline int do_rom_fast_write(struct netxen_adapter *adapter, int addr, + int data) { if (netxen_rom_wren(adapter)) { return -1; @@ -774,6 +777,11 @@ netxen_process_rcv(struct netxen_adapter PCI_DMA_FROMDEVICE); skb = (struct sk_buff *)buffer->skb; + if (buffer->rx_bounce_buff == IS_BOUNCE) { + buffer->rx_bounce_buff = 0; + memcpy(skb->data, buffer->bounce_ptr, rcv_desc->dma_size); + rx_bounce_tail = buffer->bnext; + } if (likely(STATUS_DESC_STATUS(desc) == STATUS_CKSUM_OK)) { port->stats.csummed++; @@ -938,6 +946,10 @@ void netxen_process_cmd_ring(unsigned lo PCI_DMA_TODEVICE); } + if (buffer->tx_bounce_buff == IS_BOUNCE) { + buffer->tx_bounce_buff = 0; + tx_bounce_tail = buffer->bnext; + } port->stats.skbfreed++; dev_kfree_skb_any(skb); skb = NULL; @@ -1006,6 +1018,8 @@ void netxen_post_rx_buffers(struct netxe struct netxen_rx_buffer *buffer; int count = 0; int index = 0; + unsigned long bounce_flags; + struct bounce_index tmpbi; adapter->stats.post_called++; rcv_desc = &recv_ctx->rcv_desc[ringid]; @@ -1029,6 +1043,7 @@ void netxen_post_rx_buffers(struct netxe count++; /* now there should be no failure */ pdesc = &rcv_desc->desc_head[producer]; skb_reserve(skb, NET_IP_ALIGN); + buffer->rx_bounce_buff = 0; /* * This will be setup when we receive the * buffer after it has been filled @@ -1039,6 +1054,34 @@ void netxen_post_rx_buffers(struct netxe buffer->dma = pci_map_single(pdev, skb->data, rcv_desc->dma_size, PCI_DMA_FROMDEVICE); + if (buffer->dma > NETXEN_DMA_MASK) { + pci_unmap_single(pdev, buffer->dma, rcv_desc->dma_size, + PCI_DMA_FROMDEVICE); + spin_lock_irqsave(&rx_bounce_lock, bounce_flags); + if (netxen_get_next_bounce_buffer(&rx_bounce_head, + &rx_bounce_tail, + &tmpbi, + rcv_desc->dma_size)) { + spin_unlock_irqrestore(&rx_bounce_lock, + bounce_flags); + dev_kfree_skb_any(skb); + skb = NULL; + buffer->skb = NULL; + buffer->state = NETXEN_BUFFER_FREE; + count--; + break; + } + spin_unlock_irqrestore(&rx_bounce_lock, bounce_flags); + buffer->rx_bounce_buff = IS_BOUNCE; + buffer->bnext = rx_bounce_head; + buffer->bounce_ptr = (void *)(ptrdiff_t) + (rx_bounce_ptr[tmpbi.buffer_index] + + tmpbi.buffer_offset); + buffer->dma = pci_map_single(pdev, buffer->bounce_ptr, + rcv_desc->dma_size, + PCI_DMA_FROMDEVICE); + } + /* make a rcv descriptor */ pdesc->reference_handle = le16_to_cpu(buffer->ref_handle); pdesc->buffer_length = le16_to_cpu(rcv_desc->dma_size); diff -Nupr netdev-2.6/drivers/net/netxen.two/netxen_nic_isr.c netdev-2.6/drivers/net/netxen/netxen_nic_isr.c --- netdev-2.6/drivers/net/netxen.two/netxen_nic_isr.c 2006-11-30 09:40:47.000000000 -0800 +++ netdev-2.6/drivers/net/netxen/netxen_nic_isr.c 2006-11-30 09:46:16.000000000 -0800 @@ -68,8 +68,7 @@ struct net_device_stats *netxen_nic_get_ void netxen_indicate_link_status(struct netxen_adapter *adapter, u32 portno, u32 link) { - struct netxen_port *pport = adapter->port[portno]; - struct net_device *netdev = pport->netdev; + struct net_device *netdev = (adapter->port[portno])->netdev; if (link) netif_carrier_on(netdev); diff -Nupr netdev-2.6/drivers/net/netxen.two/netxen_nic_main.c netdev-2.6/drivers/net/netxen/netxen_nic_main.c --- netdev-2.6/drivers/net/netxen.two/netxen_nic_main.c 2006-11-30 09:40:47.000000000 -0800 +++ netdev-2.6/drivers/net/netxen/netxen_nic_main.c 2006-11-30 09:46:16.000000000 -0800 @@ -48,7 +48,7 @@ MODULE_DESCRIPTION("NetXen Multi port (1 MODULE_LICENSE("GPL"); MODULE_VERSION(NETXEN_NIC_LINUX_VERSIONID); -char netxen_nic_driver_name[] = "netxen"; +char netxen_nic_driver_name[] = "netxen-nic"; static char netxen_nic_driver_string[] = "NetXen Network Driver version " NETXEN_NIC_LINUX_VERSIONID; @@ -56,6 +56,19 @@ static char netxen_nic_driver_string[] = #define NETXEN_ADAPTER_UP_MAGIC 777 #define NETXEN_NIC_PEG_TUNE 0 +/* Number of bounce buffers. Has to be a power of two */ +#define NUM_BOUNCE 256 +char *tx_bounce_ptr[NUM_BOUNCE]; +char *rx_bounce_ptr[NUM_BOUNCE]; + +struct bounce_index tx_bounce_head, tx_bounce_tail, + rx_bounce_head, rx_bounce_tail; + +spinlock_t rx_bounce_lock, tx_bounce_lock; + +#define BOUNCE_BUFFER_ORDER 2 +#define BOUNCE_BUFFER_SIZE (PAGE_SIZE << BOUNCE_BUFFER_ORDER) + /* Local functions to NetXen NIC driver */ static int __devinit netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent); @@ -88,6 +101,114 @@ static struct pci_device_id netxen_pci_t MODULE_DEVICE_TABLE(pci, netxen_pci_tbl); /* + * Whenever we cross the 16K boundary of bounce buffer, we use the next + * 16K buffer and wrap up if its the last buffer. + */ +int netxen_get_next_bounce_buffer(struct bounce_index *head, + struct bounce_index *tail, + struct bounce_index *biret, unsigned len) +{ + struct bounce_index tmpbi; + + tmpbi.buffer_index = head->buffer_index; + tmpbi.buffer_offset = head->buffer_offset; + + if ((tmpbi.buffer_offset + len) > BOUNCE_BUFFER_SIZE) { + if ((tmpbi.buffer_index == tail->buffer_index) && + (tmpbi.buffer_offset < tail->buffer_offset)) { + return -1; + } + tmpbi.buffer_index = + (tmpbi.buffer_index + 1) & (NUM_BOUNCE - 1); + tmpbi.buffer_offset = 0; + } + + if (tmpbi.buffer_index == tail->buffer_index && + tmpbi.buffer_offset < tail->buffer_offset && + (tmpbi.buffer_offset + len) >= tail->buffer_offset) { + return -1; + } + head->buffer_index = tmpbi.buffer_index; + head->buffer_offset = tmpbi.buffer_offset + len; + *biret = tmpbi; + return 0; +} + +static void netxen_free_bounce_buffers(void) +{ + int i; + + for (i = 0; i < NUM_BOUNCE && tx_bounce_ptr[i]; i++) { + free_pages((unsigned long)tx_bounce_ptr[i], + BOUNCE_BUFFER_ORDER); + tx_bounce_ptr[i] = NULL; + } + + for (i = 0; i < NUM_BOUNCE && rx_bounce_ptr[i]; i++) { + free_pages((unsigned long)rx_bounce_ptr[i], + BOUNCE_BUFFER_ORDER); + rx_bounce_ptr[i] = NULL; + } +} + +/* + * We have 4MB space reserved for bounce buffers. + * The 4MB space is divided in 256 chunks of 16K buffers. + */ +static int netxen_alloc_bounce_buffers(void) +{ + int i; + + memset(tx_bounce_ptr, 0, sizeof(tx_bounce_ptr)); + memset(rx_bounce_ptr, 0, sizeof(rx_bounce_ptr)); + + for (i = 0; i < NUM_BOUNCE; i++) { + tx_bounce_ptr[i] = (char *)__get_free_pages(GFP_KERNEL, + BOUNCE_BUFFER_ORDER); + if (!tx_bounce_ptr[i]) + goto err_out; + if (virt_to_phys(tx_bounce_ptr[i]) + + BOUNCE_BUFFER_SIZE > NETXEN_DMA_MASK) { + + free_pages((unsigned long)tx_bounce_ptr[i], + BOUNCE_BUFFER_ORDER); + tx_bounce_ptr[i] = (char *)__get_free_pages(GFP_DMA, + BOUNCE_BUFFER_ORDER); + } + if (!tx_bounce_ptr[i]) + goto err_out; + + } + tx_bounce_head.buffer_index = tx_bounce_tail.buffer_index = 0; + tx_bounce_head.buffer_offset = tx_bounce_tail.buffer_offset = 0; + + for (i = 0; i < NUM_BOUNCE; i++) { + rx_bounce_ptr[i] = (char *) + __get_free_pages(GFP_KERNEL, BOUNCE_BUFFER_ORDER); + if (!rx_bounce_ptr[i]) + goto err_out; + if (virt_to_phys(rx_bounce_ptr[i]) + + BOUNCE_BUFFER_SIZE > NETXEN_DMA_MASK) { + free_pages((unsigned long)rx_bounce_ptr[i], + BOUNCE_BUFFER_ORDER); + rx_bounce_ptr[i] = (char *) + __get_free_pages(GFP_DMA, BOUNCE_BUFFER_ORDER); + } + if (!rx_bounce_ptr[i]) + goto err_out; + + } + rx_bounce_head.buffer_index = rx_bounce_tail.buffer_index = 0; + rx_bounce_head.buffer_offset = rx_bounce_tail.buffer_offset = 0; + return 0; + + err_out: + netxen_free_bounce_buffers(); + return -ENOMEM; + +} + +/* * netxen_nic_probe() * * The Linux system will invoke this after identifying the vendor ID and @@ -105,9 +226,9 @@ netxen_nic_probe(struct pci_dev *pdev, c struct net_device *netdev = NULL; struct netxen_adapter *adapter = NULL; struct netxen_port *port = NULL; - u8 *mem_ptr0 = NULL; - u8 *mem_ptr1 = NULL; - u8 *mem_ptr2 = NULL; + void __iomem *mem_ptr0 = NULL; + void __iomem *mem_ptr1 = NULL; + void __iomem *mem_ptr2 = NULL; unsigned long mem_base, mem_len; int pci_using_dac, i, err; @@ -198,6 +319,13 @@ netxen_nic_probe(struct pci_dev *pdev, c goto err_out_free_adapter; } memset(cmd_buf_arr, 0, TX_RINGSIZE); + spin_lock_init(&tx_bounce_lock); + spin_lock_init(&rx_bounce_lock); + + /*Only one set of bounce buffers for all adapters */ + err = netxen_alloc_bounce_buffers(); + if (err) + goto err_out_fcba; for (i = 0; i < MAX_RCV_CTX; ++i) { recv_ctx = &adapter->recv_ctx[i]; @@ -308,6 +436,7 @@ netxen_nic_probe(struct pci_dev *pdev, c netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); /* initialize the all the ports */ + adapter->active_ports = 0; for (i = 0; i < adapter->ahw.max_ports; i++) { netdev = alloc_etherdev(sizeof(struct netxen_port)); @@ -392,7 +521,6 @@ netxen_nic_probe(struct pci_dev *pdev, c goto err_out_free_dev; } adapter->port_count++; - adapter->active_ports = 0; adapter->port[i] = port; } @@ -441,10 +569,9 @@ netxen_nic_probe(struct pci_dev *pdev, c } } + err_out_fcba: vfree(cmd_buf_arr); - kfree(adapter->port); - err_out_free_adapter: pci_set_drvdata(pdev, NULL); kfree(adapter); @@ -471,6 +598,7 @@ static void __devexit netxen_nic_remove( int i; int ctxid, ring; + netxen_free_bounce_buffers(); adapter = pci_get_drvdata(pdev); if (adapter == NULL) return; @@ -596,6 +724,9 @@ static int netxen_nic_open(struct net_de netxen_nic_set_link_parameters(port); netxen_nic_set_multi(netdev); + if (adapter->ops->set_mtu) + adapter->ops->set_mtu(port, netdev->mtu); + if (!adapter->driver_mismatch) netif_start_queue(netdev); @@ -675,6 +806,9 @@ static int netxen_nic_xmit_frame(struct u32 max_tx_desc_count = 0; u32 last_cmd_consumer = 0; int no_of_desc; + struct bounce_index tmpbi; + char *bounce_data; + unsigned long bounce_flags; port->stats.xmitcalled++; frag_count = skb_shinfo(skb)->nr_frags + 1; @@ -792,6 +926,7 @@ static int netxen_nic_xmit_frame(struct buffrag = &pbuf->frag_array[0]; buffrag->dma = pci_map_single(port->pdev, skb->data, first_seg_len, PCI_DMA_TODEVICE); + pbuf->tx_bounce_buff = 0; buffrag->length = first_seg_len; CMD_DESC_TOTAL_LENGTH_WRT(hwdesc, skb->len); hwdesc->num_of_buffers = frag_count; @@ -801,11 +936,33 @@ static int netxen_nic_xmit_frame(struct hwdesc->buffer1_length = cpu_to_le16(first_seg_len); hwdesc->addr_buffer1 = cpu_to_le64(buffrag->dma); + if (buffrag->dma > NETXEN_DMA_MASK) { + pci_unmap_single(port->pdev, buffrag->dma, first_seg_len, + PCI_DMA_TODEVICE); + spin_lock_irqsave(&tx_bounce_lock, bounce_flags); + if (netxen_get_next_bounce_buffer + (&tx_bounce_head, &tx_bounce_tail, &tmpbi, first_seg_len)) { + spin_unlock_irqrestore(&tx_bounce_lock, bounce_flags); + return NETDEV_TX_BUSY; + } + spin_unlock_irqrestore(&tx_bounce_lock, bounce_flags); + pbuf->tx_bounce_buff = IS_BOUNCE; + bounce_data = tx_bounce_ptr[tmpbi.buffer_index] + + tmpbi.buffer_offset; + buffrag->dma = pci_map_single(port->pdev, bounce_data, + first_seg_len, PCI_DMA_TODEVICE); + hwdesc->addr_buffer1 = buffrag->dma; + memcpy(bounce_data, skb->data, first_seg_len); + pbuf->bnext = tx_bounce_head; + } + for (i = 1, k = 1; i < frag_count; i++, k++) { struct skb_frag_struct *frag; int len, temp_len; unsigned long offset; dma_addr_t temp_dma; + struct page *bounce_frag_page; + u32 bounce_page_offset; /* move to next desc. if there is a need */ if ((i & 0x3) == 0) { @@ -827,6 +984,34 @@ static int netxen_nic_xmit_frame(struct buffrag->dma = temp_dma; buffrag->length = temp_len; + if (temp_dma > NETXEN_DMA_MASK) { + pci_unmap_single(port->pdev, temp_dma, len, + PCI_DMA_TODEVICE); + spin_lock_irqsave(&tx_bounce_lock, bounce_flags); + if (netxen_get_next_bounce_buffer(&tx_bounce_head, + &tx_bounce_tail, + &tmpbi, len)) { + spin_unlock_irqrestore(&tx_bounce_lock, + bounce_flags); + return NETDEV_TX_BUSY; + } + spin_unlock_irqrestore(&tx_bounce_lock, bounce_flags); + pbuf->tx_bounce_buff = IS_BOUNCE; + bounce_data = tx_bounce_ptr[tmpbi.buffer_index] + + tmpbi.buffer_offset; + + bounce_frag_page = virt_to_page(bounce_data); + bounce_page_offset = (unsigned long)bounce_data - + (unsigned long)page_address(bounce_frag_page); + temp_dma = pci_map_page(port->pdev, bounce_frag_page, + bounce_page_offset, len, + PCI_DMA_TODEVICE); + buffrag->dma = temp_dma; + memcpy(bounce_data, page_address(frag->page) + offset, + len); + pbuf->bnext = tx_bounce_head; + } + DPRINTK(INFO, "for loop. i=%d k=%d\n", i, k); switch (k) { case 0: @@ -1118,8 +1303,9 @@ netxen_nic_ioctl(struct net_device *netd if (ifr->ifr_data) { sprintf(dev_name, "%s-%d", NETXEN_NIC_NAME_RSP, port->portnum); - nr_bytes = copy_to_user((char *)ifr->ifr_data, dev_name, - NETXEN_NIC_NAME_LEN); + nr_bytes = + copy_to_user((char __user *)ifr->ifr_data, dev_name, + NETXEN_NIC_NAME_LEN); if (nr_bytes) err = -EIO; diff -Nupr netdev-2.6/drivers/net/netxen.two/netxen_nic_phan_reg.h netdev-2.6/drivers/net/netxen/netxen_nic_phan_reg.h --- netdev-2.6/drivers/net/netxen.two/netxen_nic_phan_reg.h 2006-11-30 09:40:47.000000000 -0800 +++ netdev-2.6/drivers/net/netxen/netxen_nic_phan_reg.h 2006-11-30 09:46:16.000000000 -0800 @@ -85,17 +85,17 @@ #define CRB_TX_PKT_TIMER NETXEN_NIC_REG(0x94) #define CRB_RX_PKT_CNT NETXEN_NIC_REG(0x98) #define CRB_RX_TMR_CNT NETXEN_NIC_REG(0x9c) -#define CRB_INT_THRESH NETXEN_NIC_REG(0xa4) +#define CRB_INT_THRESH NETXEN_NIC_REG(0xa4) /* Register for communicating XG link status */ #define CRB_XG_STATE NETXEN_NIC_REG(0xa0) /* Register for communicating card temperature */ /* Upper 16 bits are temperature value. Lower 16 bits are the state */ -#define CRB_TEMP_STATE NETXEN_NIC_REG(0xa8) -#define nx_get_temp_val(x) ((x) >> 16) -#define nx_get_temp_state(x) ((x) & 0xffff) -#define nx_encode_temp(val, state) (((val) << 16) | (state)) +#define CRB_TEMP_STATE NETXEN_NIC_REG(0xa8) +#define nx_get_temp_val(x) ((x) >> 16) +#define nx_get_temp_state(x) ((x) & 0xffff) +#define nx_encode_temp(val, state) (((val) << 16) | (state)) /* Debug registers for controlling NIC pkt gen agent */ #define CRB_AGENT_GO NETXEN_NIC_REG(0xb0) -- Don Fry [EMAIL PROTECTED] - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html