From: Don Fry <brazilnut@us.ibm.com>
To: netdev@vger.kernel.org
Cc: amitkale@netxen.com, jeff@garzik.org, netxenproj@linsyssoft.com,
rob@netxen.com, sanjeev@netxen.com, wendyx@us.ibm.com
Subject: [PATCH 3/5] NetXen: 64-bit memory fixes and driver cleanup
Date: Thu, 30 Nov 2006 10:50:57 -0800 [thread overview]
Message-ID: <20061130185057.GA32316@us.ibm.com> (raw)
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 <amitkale@netxen.com>
Signed-off-by: Don Fry <brazilnut@us.ibm.com>
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
brazilnut@us.ibm.com
reply other threads:[~2006-11-30 18:51 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20061130185057.GA32316@us.ibm.com \
--to=brazilnut@us.ibm.com \
--cc=amitkale@netxen.com \
--cc=jeff@garzik.org \
--cc=netdev@vger.kernel.org \
--cc=netxenproj@linsyssoft.com \
--cc=rob@netxen.com \
--cc=sanjeev@netxen.com \
--cc=wendyx@us.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.