u32 data;
};
-unsigned long last_schedule_time;
-
#define NETXEN_MAX_CRB_XFORM 60
static unsigned int crb_addr_xform[NETXEN_MAX_CRB_XFORM];
#define NETXEN_ADDR_ERROR (0xffffffff)
crb_addr_transform(C2C1);
crb_addr_transform(C2C0);
crb_addr_transform(SMB);
+ crb_addr_transform(OCM0);
+ crb_addr_transform(I2C0);
}
int netxen_init_firmware(struct netxen_adapter *adapter)
u32 state = 0, loops = 0, err = 0;
/* Window 1 call */
- state = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE));
+ state = adapter->pci_read_normalize(adapter, CRB_CMDPEG_STATE);
if (state == PHAN_INITIALIZE_ACK)
return 0;
while (state != PHAN_INITIALIZE_COMPLETE && loops < 2000) {
- udelay(100);
+ msleep(1);
/* Window 1 call */
- state = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE));
+ state = adapter->pci_read_normalize(adapter, CRB_CMDPEG_STATE);
loops++;
}
return err;
}
/* Window 1 call */
- writel(INTR_SCHEME_PERPORT,
- NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_CAPABILITIES_HOST));
- writel(MPORT_MULTI_FUNCTION_MODE,
- NETXEN_CRB_NORMALIZE(adapter, CRB_MPORT_MODE));
- writel(PHAN_INITIALIZE_ACK,
- NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE));
+ adapter->pci_write_normalize(adapter,
+ CRB_NIC_CAPABILITIES_HOST, INTR_SCHEME_PERPORT);
+ adapter->pci_write_normalize(adapter,
+ CRB_NIC_MSI_MODE_HOST, MSI_MODE_MULTIFUNC);
+ adapter->pci_write_normalize(adapter,
+ CRB_MPORT_MODE, MPORT_MULTI_FUNCTION_MODE);
+ adapter->pci_write_normalize(adapter,
+ CRB_CMDPEG_STATE, PHAN_INITIALIZE_ACK);
return err;
}
-#define NETXEN_ADDR_LIMIT 0xffffffffULL
+void netxen_release_rx_buffers(struct netxen_adapter *adapter)
+{
+ struct netxen_recv_context *recv_ctx;
+ struct nx_host_rds_ring *rds_ring;
+ struct netxen_rx_buffer *rx_buf;
+ int i, ctxid, ring;
-void *netxen_alloc(struct pci_dev *pdev, size_t sz, dma_addr_t * ptr,
- struct pci_dev **used_dev)
+ for (ctxid = 0; ctxid < MAX_RCV_CTX; ++ctxid) {
+ recv_ctx = &adapter->recv_ctx[ctxid];
+ for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+ rds_ring = &recv_ctx->rds_rings[ring];
+ for (i = 0; i < rds_ring->max_rx_desc_count; ++i) {
+ rx_buf = &(rds_ring->rx_buf_arr[i]);
+ if (rx_buf->state == NETXEN_BUFFER_FREE)
+ continue;
+ pci_unmap_single(adapter->pdev,
+ rx_buf->dma,
+ rds_ring->dma_size,
+ PCI_DMA_FROMDEVICE);
+ if (rx_buf->skb != NULL)
+ dev_kfree_skb_any(rx_buf->skb);
+ }
+ }
+ }
+}
+
+void netxen_release_tx_buffers(struct netxen_adapter *adapter)
{
- void *addr;
+ struct netxen_cmd_buffer *cmd_buf;
+ struct netxen_skb_frag *buffrag;
+ int i, j;
+
+ cmd_buf = adapter->cmd_buf_arr;
+ for (i = 0; i < adapter->max_tx_desc_count; i++) {
+ buffrag = cmd_buf->frag_array;
+ if (buffrag->dma) {
+ pci_unmap_single(adapter->pdev, buffrag->dma,
+ buffrag->length, PCI_DMA_TODEVICE);
+ buffrag->dma = 0ULL;
+ }
+ for (j = 0; j < cmd_buf->frag_count; j++) {
+ buffrag++;
+ if (buffrag->dma) {
+ pci_unmap_page(adapter->pdev, buffrag->dma,
+ buffrag->length,
+ PCI_DMA_TODEVICE);
+ buffrag->dma = 0ULL;
+ }
+ }
+ /* Free the skb we received in netxen_nic_xmit_frame */
+ if (cmd_buf->skb) {
+ dev_kfree_skb_any(cmd_buf->skb);
+ cmd_buf->skb = NULL;
+ }
+ cmd_buf++;
+ }
+}
- addr = pci_alloc_consistent(pdev, sz, ptr);
- if ((unsigned long long)(*ptr) < NETXEN_ADDR_LIMIT) {
- *used_dev = pdev;
- return addr;
+void netxen_free_sw_resources(struct netxen_adapter *adapter)
+{
+ struct netxen_recv_context *recv_ctx;
+ struct nx_host_rds_ring *rds_ring;
+ int ctx, ring;
+
+ for (ctx = 0; ctx < MAX_RCV_CTX; ctx++) {
+ recv_ctx = &adapter->recv_ctx[ctx];
+ for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+ rds_ring = &recv_ctx->rds_rings[ring];
+ if (rds_ring->rx_buf_arr) {
+ vfree(rds_ring->rx_buf_arr);
+ rds_ring->rx_buf_arr = NULL;
+ }
+ }
}
- pci_free_consistent(pdev, sz, addr, *ptr);
- addr = pci_alloc_consistent(NULL, sz, ptr);
- *used_dev = NULL;
- return addr;
+ if (adapter->cmd_buf_arr)
+ vfree(adapter->cmd_buf_arr);
+ return;
}
-void netxen_initialize_adapter_sw(struct netxen_adapter *adapter)
+int netxen_alloc_sw_resources(struct netxen_adapter *adapter)
{
- int ctxid, ring;
- u32 i;
- u32 num_rx_bufs = 0;
- struct netxen_rcv_desc_ctx *rcv_desc;
+ struct netxen_recv_context *recv_ctx;
+ struct nx_host_rds_ring *rds_ring;
+ struct netxen_rx_buffer *rx_buf;
+ int ctx, ring, i, num_rx_bufs;
- DPRINTK(INFO, "initializing some queues: %p\n", adapter);
- for (ctxid = 0; ctxid < MAX_RCV_CTX; ++ctxid) {
- for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
- struct netxen_rx_buffer *rx_buf;
- rcv_desc = &adapter->recv_ctx[ctxid].rcv_desc[ring];
- rcv_desc->rcv_free = rcv_desc->max_rx_desc_count;
- rcv_desc->begin_alloc = 0;
- rx_buf = rcv_desc->rx_buf_arr;
- num_rx_bufs = rcv_desc->max_rx_desc_count;
+ struct netxen_cmd_buffer *cmd_buf_arr;
+ struct net_device *netdev = adapter->netdev;
+
+ cmd_buf_arr = (struct netxen_cmd_buffer *)vmalloc(TX_RINGSIZE);
+ if (cmd_buf_arr == NULL) {
+ printk(KERN_ERR "%s: Failed to allocate cmd buffer ring\n",
+ netdev->name);
+ return -ENOMEM;
+ }
+ memset(cmd_buf_arr, 0, TX_RINGSIZE);
+ adapter->cmd_buf_arr = cmd_buf_arr;
+
+ for (ctx = 0; ctx < MAX_RCV_CTX; ctx++) {
+ recv_ctx = &adapter->recv_ctx[ctx];
+ for (ring = 0; ring < adapter->max_rds_rings; ring++) {
+ rds_ring = &recv_ctx->rds_rings[ring];
+ switch (RCV_DESC_TYPE(ring)) {
+ case RCV_DESC_NORMAL:
+ rds_ring->max_rx_desc_count =
+ adapter->max_rx_desc_count;
+ rds_ring->flags = RCV_DESC_NORMAL;
+ if (adapter->ahw.cut_through) {
+ rds_ring->dma_size =
+ NX_CT_DEFAULT_RX_BUF_LEN;
+ rds_ring->skb_size =
+ NX_CT_DEFAULT_RX_BUF_LEN;
+ } else {
+ rds_ring->dma_size = RX_DMA_MAP_LEN;
+ rds_ring->skb_size =
+ MAX_RX_BUFFER_LENGTH;
+ }
+ break;
+
+ case RCV_DESC_JUMBO:
+ rds_ring->max_rx_desc_count =
+ adapter->max_jumbo_rx_desc_count;
+ rds_ring->flags = RCV_DESC_JUMBO;
+ if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+ rds_ring->dma_size =
+ NX_P3_RX_JUMBO_BUF_MAX_LEN;
+ else
+ rds_ring->dma_size =
+ NX_P2_RX_JUMBO_BUF_MAX_LEN;
+ rds_ring->skb_size =
+ rds_ring->dma_size + NET_IP_ALIGN;
+ break;
+
+ case RCV_RING_LRO:
+ rds_ring->max_rx_desc_count =
+ adapter->max_lro_rx_desc_count;
+ rds_ring->flags = RCV_DESC_LRO;
+ rds_ring->dma_size = RX_LRO_DMA_MAP_LEN;
+ rds_ring->skb_size = MAX_RX_LRO_BUFFER_LENGTH;
+ break;
+
+ }
+ rds_ring->rx_buf_arr = (struct netxen_rx_buffer *)
+ vmalloc(RCV_BUFFSIZE);
+ if (rds_ring->rx_buf_arr == NULL) {
+ printk(KERN_ERR "%s: Failed to allocate "
+ "rx buffer ring %d\n",
+ netdev->name, ring);
+ /* free whatever was already allocated */
+ goto err_out;
+ }
+ memset(rds_ring->rx_buf_arr, 0, RCV_BUFFSIZE);
+ INIT_LIST_HEAD(&rds_ring->free_list);
+ rds_ring->begin_alloc = 0;
/*
* Now go through all of them, set reference handles
* and put them in the queues.
*/
+ num_rx_bufs = rds_ring->max_rx_desc_count;
+ rx_buf = rds_ring->rx_buf_arr;
for (i = 0; i < num_rx_bufs; i++) {
+ list_add_tail(&rx_buf->list,
+ &rds_ring->free_list);
rx_buf->ref_handle = i;
rx_buf->state = NETXEN_BUFFER_FREE;
- DPRINTK(INFO, "Rx buf:ctx%d i(%d) rx_buf:"
- "%p\n", ctxid, i, rx_buf);
rx_buf++;
}
}
}
-}
-void netxen_initialize_adapter_hw(struct netxen_adapter *adapter)
-{
- int ports = 0;
- struct netxen_board_info *board_info = &(adapter->ahw.boardcfg);
-
- if (netxen_nic_get_board_info(adapter) != 0)
- printk("%s: Error getting board config info.\n",
- netxen_nic_driver_name);
- get_brd_port_by_type(board_info->board_type, &ports);
- if (ports == 0)
- printk(KERN_ERR "%s: Unknown board type\n",
- netxen_nic_driver_name);
- adapter->ahw.max_ports = ports;
+ return 0;
+
+err_out:
+ netxen_free_sw_resources(adapter);
+ return -ENOMEM;
}
void netxen_initialize_adapter_ops(struct netxen_adapter *adapter)
netxen_niu_gbe_enable_phy_interrupts;
adapter->disable_phy_interrupts =
netxen_niu_gbe_disable_phy_interrupts;
- adapter->handle_phy_intr = netxen_nic_gbe_handle_phy_intr;
adapter->macaddr_set = netxen_niu_macaddr_set;
adapter->set_mtu = netxen_nic_set_mtu_gb;
adapter->set_promisc = netxen_niu_set_promiscuous_mode;
- adapter->unset_promisc = netxen_niu_set_promiscuous_mode;
adapter->phy_read = netxen_niu_gbe_phy_read;
adapter->phy_write = netxen_niu_gbe_phy_write;
- adapter->init_niu = netxen_nic_init_niu_gb;
+ adapter->init_port = netxen_niu_gbe_init_port;
adapter->stop_port = netxen_niu_disable_gbe_port;
break;
netxen_niu_xgbe_enable_phy_interrupts;
adapter->disable_phy_interrupts =
netxen_niu_xgbe_disable_phy_interrupts;
- adapter->handle_phy_intr = netxen_nic_xgbe_handle_phy_intr;
adapter->macaddr_set = netxen_niu_xg_macaddr_set;
adapter->set_mtu = netxen_nic_set_mtu_xgb;
adapter->init_port = netxen_niu_xg_init_port;
adapter->set_promisc = netxen_niu_xg_set_promiscuous_mode;
- adapter->unset_promisc = netxen_niu_xg_set_promiscuous_mode;
adapter->stop_port = netxen_niu_disable_xg_port;
break;
static long rom_max_timeout = 100;
static long rom_lock_timeout = 10000;
+#if 0
static long rom_write_timeout = 700;
+#endif
static int rom_lock(struct netxen_adapter *adapter)
{
return 0;
}
+#if 0
static int netxen_rom_wren(struct netxen_adapter *adapter)
{
/* Set write enable latch in ROM status register */
}
return netxen_rdcrbreg(adapter, NETXEN_ROMUSB_ROM_RDATA);
}
+#endif
static void netxen_rom_unlock(struct netxen_adapter *adapter)
{
}
+#if 0
static int netxen_rom_wip_poll(struct netxen_adapter *adapter)
{
long timeout = 0;
return netxen_rom_wip_poll(adapter);
}
+#endif
static int do_rom_fast_read(struct netxen_adapter *adapter,
int addr, int *valp)
int ret = 0;
for (addridx = addr; addridx < (addr + size); addridx += 4) {
- ret = do_rom_fast_read(adapter, addridx, (int *)bytes);
+ int v;
+ ret = do_rom_fast_read(adapter, addridx, &v);
if (ret != 0)
break;
- *(int *)bytes = cpu_to_le32(*(int *)bytes);
+ *(__le32 *)bytes = cpu_to_le32(v);
bytes += 4;
}
}
int
-netxen_rom_fast_read_words(struct netxen_adapter *adapter, int addr,
+netxen_rom_fast_read_words(struct netxen_adapter *adapter, int addr,
u8 *bytes, size_t size)
{
int ret;
netxen_rom_unlock(adapter);
return ret;
}
-#endif /* 0 */
-static int do_rom_fast_write_words(struct netxen_adapter *adapter,
+static int do_rom_fast_write_words(struct netxen_adapter *adapter,
int addr, u8 *bytes, size_t size)
{
int addridx = addr;
int timeout = 0;
int data;
- data = le32_to_cpu((*(u32*)bytes));
+ data = le32_to_cpu((*(__le32*)bytes));
ret = do_rom_fast_write(adapter, addridx, data);
if (ret < 0)
return ret;
-
+
while(1) {
int data1;
if (timeout++ >= rom_write_timeout) {
if (last_attempt++ < 4) {
- ret = do_rom_fast_write(adapter,
+ ret = do_rom_fast_write(adapter,
addridx, data);
if (ret < 0)
return ret;
return ret;
}
-int netxen_rom_fast_write_words(struct netxen_adapter *adapter, int addr,
+int netxen_rom_fast_write_words(struct netxen_adapter *adapter, int addr,
u8 *bytes, size_t size)
{
int ret = 0;
return ret;
netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_ROM_WDATA, data);
- netxen_crb_writelit_adapter(adapter,
+ netxen_crb_writelit_adapter(adapter,
NETXEN_ROMUSB_ROM_INSTR_OPCODE, 0x1);
ret = netxen_wait_rom_done(adapter);
char *buffer = kmalloc(NETXEN_FLASH_SECTOR_SIZE, GFP_KERNEL);
if (!buffer)
- return -ENOMEM;
+ return -ENOMEM;
/* unlock sector 63 */
val = netxen_rom_rdsr(adapter);
val = val & 0xe3;
goto out_kfree;
/* copy sector 0 to sector 63 */
- ret = netxen_rom_fast_read_words(adapter, NETXEN_CRBINIT_START,
+ ret = netxen_rom_fast_read_words(adapter, NETXEN_CRBINIT_START,
buffer, NETXEN_FLASH_SECTOR_SIZE);
if (ret != FLASH_SUCCESS)
goto out_kfree;
- ret = netxen_rom_fast_write_words(adapter, NETXEN_FIXED_START,
+ ret = netxen_rom_fast_write_words(adapter, NETXEN_FIXED_START,
buffer, NETXEN_FLASH_SECTOR_SIZE);
if (ret != FLASH_SUCCESS)
goto out_kfree;
int count = 0, erased_errors = 0;
int range;
- range = (addr == NETXEN_USER_START) ?
+ range = (addr == NETXEN_USER_START) ?
NETXEN_FIXED_START : addr + NETXEN_FLASH_SECTOR_SIZE;
-
+
for (i = addr; i < range; i += 4) {
netxen_rom_fast_read(adapter, i, &val);
if (val != 0xffffffff)
return ret;
}
+#endif /* 0 */
#define NETXEN_BOARDTYPE 0x4008
#define NETXEN_BOARDNUM 0x400c
#define NETXEN_CHIPNUM 0x4010
-#define NETXEN_ROMBUS_RESET 0xFFFFFFFF
-#define NETXEN_ROM_FIRST_BARRIER 0x800000000ULL
-#define NETXEN_ROM_FOUND_INIT 0x400
int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
{
- int addr, val, status;
- int n, i;
- int init_delay = 0;
+ int addr, val;
+ int i, init_delay = 0;
struct crb_addr_pair *buf;
+ unsigned offset, n;
u32 off;
/* resetall */
- status = netxen_nic_get_board_info(adapter);
- if (status)
- printk("%s: netxen_pinit_from_rom: Error getting board info\n",
- netxen_nic_driver_name);
-
netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_GLB_SW_RESET,
- NETXEN_ROMBUS_RESET);
+ 0xffffffff);
if (verbose) {
- int val;
if (netxen_rom_fast_read(adapter, NETXEN_BOARDTYPE, &val) == 0)
printk("P2 ROM board type: 0x%08x\n", val);
else
printk("Could not read chip number\n");
}
- if (netxen_rom_fast_read(adapter, 0, &n) == 0
- && (n & NETXEN_ROM_FIRST_BARRIER)) {
- n &= ~NETXEN_ROM_ROUNDUP;
- if (n < NETXEN_ROM_FOUND_INIT) {
- if (verbose)
- printk("%s: %d CRB init values found"
- " in ROM.\n", netxen_nic_driver_name, n);
- } else {
- printk("%s:n=0x%x Error! NetXen card flash not"
- " initialized.\n", __FUNCTION__, n);
+ if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+ if (netxen_rom_fast_read(adapter, 0, &n) != 0 ||
+ (n != 0xcafecafeUL) ||
+ netxen_rom_fast_read(adapter, 4, &n) != 0) {
+ printk(KERN_ERR "%s: ERROR Reading crb_init area: "
+ "n: %08x\n", netxen_nic_driver_name, n);
return -EIO;
}
- buf = kcalloc(n, sizeof(struct crb_addr_pair), GFP_KERNEL);
- if (buf == NULL) {
- printk("%s: netxen_pinit_from_rom: Unable to calloc "
- "memory.\n", netxen_nic_driver_name);
- return -ENOMEM;
- }
- for (i = 0; i < n; i++) {
- if (netxen_rom_fast_read(adapter, 8 * i + 4, &val) != 0
- || netxen_rom_fast_read(adapter, 8 * i + 8,
- &addr) != 0)
- return -EIO;
-
- buf[i].addr = addr;
- buf[i].data = val;
-
- if (verbose)
- printk("%s: PCI: 0x%08x == 0x%08x\n",
- netxen_nic_driver_name, (unsigned int)
- netxen_decode_crb_addr(addr), val);
+ offset = n & 0xffffU;
+ n = (n >> 16) & 0xffffU;
+ } else {
+ if (netxen_rom_fast_read(adapter, 0, &n) != 0 ||
+ !(n & 0x80000000)) {
+ printk(KERN_ERR "%s: ERROR Reading crb_init area: "
+ "n: %08x\n", netxen_nic_driver_name, n);
+ return -EIO;
}
- for (i = 0; i < n; i++) {
+ offset = 1;
+ n &= ~0x80000000;
+ }
+
+ if (n < 1024) {
+ if (verbose)
+ printk(KERN_DEBUG "%s: %d CRB init values found"
+ " in ROM.\n", netxen_nic_driver_name, n);
+ } else {
+ printk(KERN_ERR "%s:n=0x%x Error! NetXen card flash not"
+ " initialized.\n", __func__, n);
+ return -EIO;
+ }
+
+ buf = kcalloc(n, sizeof(struct crb_addr_pair), GFP_KERNEL);
+ if (buf == NULL) {
+ printk("%s: netxen_pinit_from_rom: Unable to calloc memory.\n",
+ netxen_nic_driver_name);
+ return -ENOMEM;
+ }
+ for (i = 0; i < n; i++) {
+ if (netxen_rom_fast_read(adapter, 8*i + 4*offset, &val) != 0 ||
+ netxen_rom_fast_read(adapter, 8*i + 4*offset + 4, &addr) != 0)
+ return -EIO;
+
+ buf[i].addr = addr;
+ buf[i].data = val;
+
+ if (verbose)
+ printk(KERN_DEBUG "%s: PCI: 0x%08x == 0x%08x\n",
+ netxen_nic_driver_name,
+ (u32)netxen_decode_crb_addr(addr), val);
+ }
+ for (i = 0; i < n; i++) {
- off = netxen_decode_crb_addr(buf[i].addr);
- if (off == NETXEN_ADDR_ERROR) {
- printk(KERN_ERR"CRB init value out of range %x\n",
+ off = netxen_decode_crb_addr(buf[i].addr);
+ if (off == NETXEN_ADDR_ERROR) {
+ printk(KERN_ERR"CRB init value out of range %x\n",
buf[i].addr);
+ continue;
+ }
+ off += NETXEN_PCI_CRBSPACE;
+ /* skipping cold reboot MAGIC */
+ if (off == NETXEN_CAM_RAM(0x1fc))
+ continue;
+
+ if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+ /* do not reset PCI */
+ if (off == (ROMUSB_GLB + 0xbc))
continue;
- }
- off += NETXEN_PCI_CRBSPACE;
- /* skipping cold reboot MAGIC */
- if (off == NETXEN_CAM_RAM(0x1fc))
+ if (off == (NETXEN_CRB_PEG_NET_1 + 0x18))
+ buf[i].data = 0x1020;
+ /* skip the function enable register */
+ if (off == NETXEN_PCIE_REG(PCIE_SETUP_FUNCTION))
+ continue;
+ if (off == NETXEN_PCIE_REG(PCIE_SETUP_FUNCTION2))
+ continue;
+ if ((off & 0x0ff00000) == NETXEN_CRB_SMB)
continue;
+ }
+
+ if (off == NETXEN_ADDR_ERROR) {
+ printk(KERN_ERR "%s: Err: Unknown addr: 0x%08x\n",
+ netxen_nic_driver_name, buf[i].addr);
+ continue;
+ }
- /* After writing this register, HW needs time for CRB */
- /* to quiet down (else crb_window returns 0xffffffff) */
- if (off == NETXEN_ROMUSB_GLB_SW_RESET) {
- init_delay = 1;
+ /* After writing this register, HW needs time for CRB */
+ /* to quiet down (else crb_window returns 0xffffffff) */
+ if (off == NETXEN_ROMUSB_GLB_SW_RESET) {
+ init_delay = 1;
+ if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
/* hold xdma in reset also */
buf[i].data = NETXEN_NIC_XDMA_RESET;
}
+ }
- if (ADDR_IN_WINDOW1(off)) {
- writel(buf[i].data,
- NETXEN_CRB_NORMALIZE(adapter, off));
- } else {
- netxen_nic_pci_change_crbwindow(adapter, 0);
- writel(buf[i].data,
- pci_base_offset(adapter, off));
+ adapter->hw_write_wx(adapter, off, &buf[i].data, 4);
- netxen_nic_pci_change_crbwindow(adapter, 1);
- }
- if (init_delay == 1) {
- msleep(2000);
- init_delay = 0;
- }
- msleep(20);
+ if (init_delay == 1) {
+ msleep(1000);
+ init_delay = 0;
}
- kfree(buf);
+ msleep(1);
+ }
+ kfree(buf);
- /* disable_peg_cache_all */
+ /* disable_peg_cache_all */
- /* unreset_net_cache */
- netxen_nic_hw_read_wx(adapter, NETXEN_ROMUSB_GLB_SW_RESET, &val,
- 4);
- netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_GLB_SW_RESET,
- (val & 0xffffff0f));
- /* p2dn replyCount */
- netxen_crb_writelit_adapter(adapter,
- NETXEN_CRB_PEG_NET_D + 0xec, 0x1e);
- /* disable_peg_cache 0 */
+ /* unreset_net_cache */
+ if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+ adapter->hw_read_wx(adapter,
+ NETXEN_ROMUSB_GLB_SW_RESET, &val, 4);
netxen_crb_writelit_adapter(adapter,
- NETXEN_CRB_PEG_NET_D + 0x4c, 8);
- /* disable_peg_cache 1 */
- netxen_crb_writelit_adapter(adapter,
- NETXEN_CRB_PEG_NET_I + 0x4c, 8);
-
- /* peg_clr_all */
-
- /* peg_clr 0 */
- netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_0 + 0x8,
- 0);
- netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_0 + 0xc,
- 0);
- /* peg_clr 1 */
- netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_1 + 0x8,
- 0);
- netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_1 + 0xc,
- 0);
- /* peg_clr 2 */
- netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_2 + 0x8,
- 0);
- netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_2 + 0xc,
- 0);
- /* peg_clr 3 */
- netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_3 + 0x8,
- 0);
- netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_3 + 0xc,
- 0);
+ NETXEN_ROMUSB_GLB_SW_RESET, (val & 0xffffff0f));
}
+
+ /* p2dn replyCount */
+ netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_D + 0xec, 0x1e);
+ /* disable_peg_cache 0 */
+ netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_D + 0x4c, 8);
+ /* disable_peg_cache 1 */
+ netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_I + 0x4c, 8);
+
+ /* peg_clr_all */
+
+ /* peg_clr 0 */
+ netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_0 + 0x8, 0);
+ netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_0 + 0xc, 0);
+ /* peg_clr 1 */
+ netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_1 + 0x8, 0);
+ netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_1 + 0xc, 0);
+ /* peg_clr 2 */
+ netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_2 + 0x8, 0);
+ netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_2 + 0xc, 0);
+ /* peg_clr 3 */
+ netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_3 + 0x8, 0);
+ netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_3 + 0xc, 0);
return 0;
}
uint32_t lo;
adapter->dummy_dma.addr =
- pci_alloc_consistent(adapter->ahw.pdev,
+ pci_alloc_consistent(adapter->pdev,
NETXEN_HOST_DUMMY_DMA_SIZE,
&adapter->dummy_dma.phys_addr);
if (adapter->dummy_dma.addr == NULL) {
printk("%s: ERROR: Could not allocate dummy DMA memory\n",
- __FUNCTION__);
+ __func__);
return -ENOMEM;
}
hi = (addr >> 32) & 0xffffffff;
lo = addr & 0xffffffff;
- writel(hi, NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_DUMMY_BUF_ADDR_HI));
- writel(lo, NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_DUMMY_BUF_ADDR_LO));
+ adapter->pci_write_normalize(adapter, CRB_HOST_DUMMY_BUF_ADDR_HI, hi);
+ adapter->pci_write_normalize(adapter, CRB_HOST_DUMMY_BUF_ADDR_LO, lo);
+
+ if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+ uint32_t temp = 0;
+ adapter->hw_write_wx(adapter, CRB_HOST_DUMMY_BUF, &temp, 4);
+ }
return 0;
}
void netxen_free_adapter_offload(struct netxen_adapter *adapter)
{
+ int i;
+
if (adapter->dummy_dma.addr) {
- pci_free_consistent(adapter->ahw.pdev,
+ i = 100;
+ do {
+ if (dma_watchdog_shutdown_request(adapter) == 1)
+ break;
+ msleep(50);
+ if (dma_watchdog_shutdown_poll_result(adapter) == 1)
+ break;
+ } while (--i);
+
+ if (i) {
+ pci_free_consistent(adapter->pdev,
NETXEN_HOST_DUMMY_DMA_SIZE,
adapter->dummy_dma.addr,
adapter->dummy_dma.phys_addr);
- adapter->dummy_dma.addr = NULL;
+ adapter->dummy_dma.addr = NULL;
+ } else {
+ printk(KERN_ERR "%s: dma_watchdog_shutdown failed\n",
+ adapter->netdev->name);
+ }
}
}
int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val)
{
u32 val = 0;
- int retries = 30;
+ int retries = 60;
if (!pegtune_val) {
do {
- val = readl(NETXEN_CRB_NORMALIZE
- (adapter, CRB_CMDPEG_STATE));
- pegtune_val = readl(NETXEN_CRB_NORMALIZE
- (adapter, NETXEN_ROMUSB_GLB_PEGTUNE_DONE));
+ val = adapter->pci_read_normalize(adapter,
+ CRB_CMDPEG_STATE);
if (val == PHAN_INITIALIZE_COMPLETE ||
val == PHAN_INITIALIZE_ACK)
return 0;
- msleep(1000);
+ msleep(500);
+
} while (--retries);
+
if (!retries) {
+ pegtune_val = adapter->pci_read_normalize(adapter,
+ NETXEN_ROMUSB_GLB_PEGTUNE_DONE);
printk(KERN_WARNING "netxen_phantom_init: init failed, "
"pegtune_val=%x\n", pegtune_val);
return -1;
return 0;
}
-int netxen_nic_rx_has_work(struct netxen_adapter *adapter)
+int netxen_receive_peg_ready(struct netxen_adapter *adapter)
{
- int ctx;
+ u32 val = 0;
+ int retries = 2000;
- for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
- struct netxen_recv_context *recv_ctx =
- &(adapter->recv_ctx[ctx]);
- u32 consumer;
- struct status_desc *desc_head;
- struct status_desc *desc;
+ do {
+ val = adapter->pci_read_normalize(adapter, CRB_RCVPEG_STATE);
- consumer = recv_ctx->status_rx_consumer;
- desc_head = recv_ctx->rcv_status_desc_head;
- desc = &desc_head[consumer];
+ if (val == PHAN_PEG_RCV_INITIALIZED)
+ return 0;
+
+ msleep(10);
+
+ } while (--retries);
- if (netxen_get_sts_owner(desc) & STATUS_OWNER_HOST)
- return 1;
+ if (!retries) {
+ printk(KERN_ERR "Receive Peg initialization not "
+ "complete, state: 0x%x.\n", val);
+ return -EIO;
}
return 0;
}
-static int netxen_nic_check_temp(struct netxen_adapter *adapter)
+static struct sk_buff *netxen_process_rxbuf(struct netxen_adapter *adapter,
+ struct nx_host_rds_ring *rds_ring, u16 index, u16 cksum)
{
- struct net_device *netdev = adapter->netdev;
- uint32_t temp, temp_state, temp_val;
- int rv = 0;
-
- temp = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_TEMP_STATE));
-
- temp_state = nx_get_temp_state(temp);
- temp_val = nx_get_temp_val(temp);
-
- if (temp_state == NX_TEMP_PANIC) {
- printk(KERN_ALERT
- "%s: Device temperature %d degrees C exceeds"
- " maximum allowed. Hardware has been shut down.\n",
- netxen_nic_driver_name, temp_val);
-
- netif_carrier_off(netdev);
- netif_stop_queue(netdev);
- rv = 1;
- } else if (temp_state == NX_TEMP_WARN) {
- if (adapter->temp == NX_TEMP_NORMAL) {
- printk(KERN_ALERT
- "%s: Device temperature %d degrees C "
- "exceeds operating range."
- " Immediate action needed.\n",
- netxen_nic_driver_name, temp_val);
- }
- } else {
- if (adapter->temp == NX_TEMP_WARN) {
- printk(KERN_INFO
- "%s: Device temperature is now %d degrees C"
- " in normal range.\n", netxen_nic_driver_name,
- temp_val);
- }
- }
- adapter->temp = temp_state;
- return rv;
-}
+ struct netxen_rx_buffer *buffer;
+ struct sk_buff *skb;
-void netxen_watchdog_task(struct work_struct *work)
-{
- struct net_device *netdev;
- struct netxen_adapter *adapter =
- container_of(work, struct netxen_adapter, watchdog_task);
+ buffer = &rds_ring->rx_buf_arr[index];
- if ((adapter->portnum == 0) && netxen_nic_check_temp(adapter))
- return;
+ pci_unmap_single(adapter->pdev, buffer->dma, rds_ring->dma_size,
+ PCI_DMA_FROMDEVICE);
- if (adapter->handle_phy_intr)
- adapter->handle_phy_intr(adapter);
-
- netdev = adapter->netdev;
- if ((netif_running(netdev)) && !netif_carrier_ok(netdev) &&
- netxen_nic_link_ok(adapter) ) {
- printk(KERN_INFO "%s %s (port %d), Link is up\n",
- netxen_nic_driver_name, netdev->name, adapter->portnum);
- netif_carrier_on(netdev);
- netif_wake_queue(netdev);
- } else if(!(netif_running(netdev)) && netif_carrier_ok(netdev)) {
- printk(KERN_ERR "%s %s Link is Down\n",
- netxen_nic_driver_name, netdev->name);
- netif_carrier_off(netdev);
- netif_stop_queue(netdev);
- }
+ skb = buffer->skb;
+ if (!skb)
+ goto no_skb;
+
+ if (likely(adapter->rx_csum && cksum == STATUS_CKSUM_OK)) {
+ adapter->stats.csummed++;
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ } else
+ skb->ip_summed = CHECKSUM_NONE;
+
+ skb->dev = adapter->netdev;
+
+ buffer->skb = NULL;
- mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
+no_skb:
+ buffer->state = NETXEN_BUFFER_FREE;
+ buffer->lro_current_frags = 0;
+ buffer->lro_expected_frags = 0;
+ list_add_tail(&buffer->list, &rds_ring->free_list);
+ return skb;
}
/*
* invoke the routine to send more rx buffers to the Phantom...
*/
static void netxen_process_rcv(struct netxen_adapter *adapter, int ctxid,
- struct status_desc *desc)
+ struct status_desc *desc, struct status_desc *frag_desc)
{
- struct pci_dev *pdev = adapter->pdev;
struct net_device *netdev = adapter->netdev;
u64 sts_data = le64_to_cpu(desc->status_desc_data);
int index = netxen_get_sts_refhandle(sts_data);
struct sk_buff *skb;
u32 length = netxen_get_sts_totallength(sts_data);
u32 desc_ctx;
- struct netxen_rcv_desc_ctx *rcv_desc;
- int ret;
+ u16 pkt_offset = 0, cksum;
+ struct nx_host_rds_ring *rds_ring;
desc_ctx = netxen_get_sts_type(sts_data);
if (unlikely(desc_ctx >= NUM_RCV_DESC_RINGS)) {
return;
}
- rcv_desc = &recv_ctx->rcv_desc[desc_ctx];
- if (unlikely(index > rcv_desc->max_rx_desc_count)) {
+ rds_ring = &recv_ctx->rds_rings[desc_ctx];
+ if (unlikely(index > rds_ring->max_rx_desc_count)) {
DPRINTK(ERR, "Got a buffer index:%x Max is %x\n",
- index, rcv_desc->max_rx_desc_count);
+ index, rds_ring->max_rx_desc_count);
return;
}
- buffer = &rcv_desc->rx_buf_arr[index];
+ buffer = &rds_ring->rx_buf_arr[index];
if (desc_ctx == RCV_DESC_LRO_CTXID) {
buffer->lro_current_frags++;
if (netxen_get_sts_desc_lro_last_frag(desc)) {
}
}
- pci_unmap_single(pdev, buffer->dma, rcv_desc->dma_size,
- PCI_DMA_FROMDEVICE);
-
- skb = (struct sk_buff *)buffer->skb;
+ cksum = netxen_get_sts_status(sts_data);
- if (likely(adapter->rx_csum &&
- netxen_get_sts_status(sts_data) == STATUS_CKSUM_OK)) {
- adapter->stats.csummed++;
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- } else
- skb->ip_summed = CHECKSUM_NONE;
+ skb = netxen_process_rxbuf(adapter, rds_ring, index, cksum);
+ if (!skb)
+ return;
- 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);
} else {
- skb_put(skb, length);
+ if (length > rds_ring->skb_size)
+ skb_put(skb, rds_ring->skb_size);
+ else
+ skb_put(skb, length);
+
+ pkt_offset = netxen_get_sts_pkt_offset(sts_data);
+ if (pkt_offset)
+ skb_pull(skb, pkt_offset);
}
skb->protocol = eth_type_trans(skb, netdev);
- ret = netif_receive_skb(skb);
-
/*
- * RH: Do we need these stats on a regular basis. Can we get it from
- * Linux stats.
+ * rx buffer chaining is disabled, walk and free
+ * any spurious rx buffer chain.
*/
- switch (ret) {
- case NET_RX_SUCCESS:
- adapter->stats.uphappy++;
- break;
-
- case NET_RX_CN_LOW:
- adapter->stats.uplcong++;
- break;
-
- case NET_RX_CN_MOD:
- adapter->stats.upmcong++;
- break;
-
- case NET_RX_CN_HIGH:
- adapter->stats.uphcong++;
- break;
+ if (frag_desc) {
+ u16 i, nr_frags = desc->nr_frags;
+
+ dev_kfree_skb_any(skb);
+ for (i = 0; i < nr_frags; i++) {
+ index = frag_desc->frag_handles[i];
+ skb = netxen_process_rxbuf(adapter,
+ rds_ring, index, cksum);
+ if (skb)
+ dev_kfree_skb_any(skb);
+ }
+ adapter->stats.rxdropped++;
+ } else {
- case NET_RX_DROP:
- adapter->stats.updropped++;
- break;
+ netif_receive_skb(skb);
+ netdev->last_rx = jiffies;
- default:
- adapter->stats.updunno++;
- break;
+ adapter->stats.no_rcv++;
+ adapter->stats.rxbytes += length;
}
-
- netdev->last_rx = jiffies;
-
- rcv_desc->rcv_free++;
- rcv_desc->rcv_pending--;
-
- /*
- * We just consumed one buffer so post a buffer.
- */
- buffer->skb = NULL;
- buffer->state = NETXEN_BUFFER_FREE;
- buffer->lro_current_frags = 0;
- buffer->lro_expected_frags = 0;
-
- adapter->stats.no_rcv++;
- adapter->stats.rxbytes += length;
}
/* Process Receive status ring */
{
struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctxid]);
struct status_desc *desc_head = recv_ctx->rcv_status_desc_head;
- struct status_desc *desc; /* used to read status desc here */
+ struct status_desc *desc, *frag_desc;
u32 consumer = recv_ctx->status_rx_consumer;
- u32 producer = 0;
int count = 0, ring;
+ u64 sts_data;
+ u16 opcode;
- DPRINTK(INFO, "procesing receive\n");
- /*
- * we assume in this case that there is only one port and that is
- * port #1...changes need to be done in firmware to indicate port
- * number as part of the descriptor. This way we will be able to get
- * the netdev which is associated with that device.
- */
while (count < max) {
desc = &desc_head[consumer];
if (!(netxen_get_sts_owner(desc) & STATUS_OWNER_HOST)) {
netxen_get_sts_owner(desc));
break;
}
- netxen_process_rcv(adapter, ctxid, desc);
+
+ sts_data = le64_to_cpu(desc->status_desc_data);
+ opcode = netxen_get_sts_opcode(sts_data);
+ frag_desc = NULL;
+ if (opcode == NETXEN_NIC_RXPKT_DESC) {
+ if (desc->nr_frags) {
+ consumer = get_next_index(consumer,
+ adapter->max_rx_desc_count);
+ frag_desc = &desc_head[consumer];
+ netxen_set_sts_owner(frag_desc,
+ STATUS_OWNER_PHANTOM);
+ }
+ }
+
+ netxen_process_rcv(adapter, ctxid, desc, frag_desc);
+
netxen_set_sts_owner(desc, STATUS_OWNER_PHANTOM);
- consumer = (consumer + 1) & (adapter->max_rx_desc_count - 1);
+
+ consumer = get_next_index(consumer,
+ adapter->max_rx_desc_count);
count++;
}
- if (count) {
- for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
- netxen_post_rx_buffers_nodb(adapter, ctxid, ring);
- }
- }
+ for (ring = 0; ring < adapter->max_rds_rings; ring++)
+ netxen_post_rx_buffers_nodb(adapter, ctxid, ring);
/* update the consumer index in phantom */
if (count) {
recv_ctx->status_rx_consumer = consumer;
- recv_ctx->status_rx_producer = producer;
/* Window = 1 */
- writel(consumer,
- NETXEN_CRB_NORMALIZE(adapter,
- recv_crb_registers[adapter->portnum].
- crb_rcv_status_consumer));
- wmb();
+ adapter->pci_write_normalize(adapter,
+ recv_ctx->crb_sts_consumer, consumer);
}
return count;
}
/* Process Command status ring */
-int netxen_process_cmd_ring(unsigned long data)
+int netxen_process_cmd_ring(struct netxen_adapter *adapter)
{
- u32 last_consumer;
- u32 consumer;
- struct netxen_adapter *adapter = (struct netxen_adapter *)data;
- int count1 = 0;
- int count2 = 0;
+ u32 last_consumer, consumer;
+ int count = 0, i;
struct netxen_cmd_buffer *buffer;
- struct pci_dev *pdev;
+ struct pci_dev *pdev = adapter->pdev;
+ struct net_device *netdev = adapter->netdev;
struct netxen_skb_frag *frag;
- u32 i;
- int done;
+ int done = 0;
- spin_lock(&adapter->tx_lock);
last_consumer = adapter->last_cmd_consumer;
- DPRINTK(INFO, "procesing xmit complete\n");
- /* we assume in this case that there is only one port and that is
- * port #1...changes need to be done in firmware to indicate port
- * number as part of the descriptor. This way we will be able to get
- * the netdev which is associated with that device.
- */
-
consumer = le32_to_cpu(*(adapter->cmd_consumer));
- if (last_consumer == consumer) { /* Ring is empty */
- DPRINTK(INFO, "last_consumer %d == consumer %d\n",
- last_consumer, consumer);
- spin_unlock(&adapter->tx_lock);
- return 1;
- }
-
- adapter->proc_cmd_buf_counter++;
- /*
- * Not needed - does not seem to be used anywhere.
- * adapter->cmd_consumer = consumer;
- */
- spin_unlock(&adapter->tx_lock);
- while ((last_consumer != consumer) && (count1 < MAX_STATUS_HANDLE)) {
+ while (last_consumer != consumer) {
buffer = &adapter->cmd_buf_arr[last_consumer];
- pdev = adapter->pdev;
if (buffer->skb) {
frag = &buffer->frag_array[0];
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++;
+ adapter->stats.xmitfinished++;
dev_kfree_skb_any(buffer->skb);
buffer->skb = NULL;
- } else if (adapter->proc_cmd_buf_counter == 1) {
- adapter->stats.txnullskb++;
- }
- if (unlikely(netif_queue_stopped(adapter->netdev)
- && netif_carrier_ok(adapter->netdev))
- && ((jiffies - adapter->netdev->trans_start) >
- adapter->netdev->watchdog_timeo)) {
- SCHEDULE_WORK(&adapter->tx_timeout_task);
}
last_consumer = get_next_index(last_consumer,
adapter->max_tx_desc_count);
- count1++;
+ if (++count >= MAX_STATUS_HANDLE)
+ break;
}
- count2 = 0;
- spin_lock(&adapter->tx_lock);
- if ((--adapter->proc_cmd_buf_counter) == 0) {
+ if (count) {
adapter->last_cmd_consumer = last_consumer;
- while ((adapter->last_cmd_consumer != consumer)
- && (count2 < MAX_STATUS_HANDLE)) {
- buffer =
- &adapter->cmd_buf_arr[adapter->last_cmd_consumer];
- count2++;
- if (buffer->skb)
- break;
- else
- adapter->last_cmd_consumer =
- get_next_index(adapter->last_cmd_consumer,
- adapter->max_tx_desc_count);
- }
- }
- if (count1 || count2) {
- if (netif_queue_stopped(adapter->netdev)
- && (adapter->flags & NETXEN_NETDEV_STATUS)) {
- netif_wake_queue(adapter->netdev);
- adapter->flags &= ~NETXEN_NETDEV_STATUS;
+ smp_mb();
+ if (netif_queue_stopped(netdev) && netif_running(netdev)) {
+ netif_tx_lock(netdev);
+ netif_wake_queue(netdev);
+ smp_mb();
+ netif_tx_unlock(netdev);
}
}
/*
* There is still a possible race condition and the host could miss an
* interrupt. The card has to take care of this.
*/
- if (adapter->last_cmd_consumer == consumer &&
- (((adapter->cmd_producer + 1) %
- adapter->max_tx_desc_count) == adapter->last_cmd_consumer)) {
- consumer = le32_to_cpu(*(adapter->cmd_consumer));
- }
- done = (adapter->last_cmd_consumer == consumer);
+ consumer = le32_to_cpu(*(adapter->cmd_consumer));
+ done = (last_consumer == consumer);
- spin_unlock(&adapter->tx_lock);
- DPRINTK(INFO, "last consumer is %d in %s\n", last_consumer,
- __FUNCTION__);
return (done);
}
*/
void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid)
{
- struct pci_dev *pdev = adapter->ahw.pdev;
+ struct pci_dev *pdev = adapter->pdev;
struct sk_buff *skb;
struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctx]);
- struct netxen_rcv_desc_ctx *rcv_desc = NULL;
+ struct nx_host_rds_ring *rds_ring = NULL;
uint producer;
struct rcv_desc *pdesc;
struct netxen_rx_buffer *buffer;
int index = 0;
netxen_ctx_msg msg = 0;
dma_addr_t dma;
+ struct list_head *head;
- rcv_desc = &recv_ctx->rcv_desc[ringid];
+ rds_ring = &recv_ctx->rds_rings[ringid];
+
+ producer = rds_ring->producer;
+ index = rds_ring->begin_alloc;
+ head = &rds_ring->free_list;
- producer = rcv_desc->producer;
- index = rcv_desc->begin_alloc;
- buffer = &rcv_desc->rx_buf_arr[index];
/* We can start writing rx descriptors into the phantom memory. */
- while (buffer->state == NETXEN_BUFFER_FREE) {
- skb = dev_alloc_skb(rcv_desc->skb_size);
+ while (!list_empty(head)) {
+
+ skb = dev_alloc_skb(rds_ring->skb_size);
if (unlikely(!skb)) {
- /*
- * TODO
- * We need to schedule the posting of buffers to the pegs.
- */
- rcv_desc->begin_alloc = index;
- DPRINTK(ERR, "netxen_post_rx_buffers: "
- " allocated only %d buffers\n", count);
+ rds_ring->begin_alloc = index;
break;
}
+ buffer = list_entry(head->next, struct netxen_rx_buffer, list);
+ list_del(&buffer->list);
+
count++; /* now there should be no failure */
- pdesc = &rcv_desc->desc_head[producer];
+ pdesc = &rds_ring->desc_head[producer];
-#if defined(XGB_DEBUG)
- *(unsigned long *)(skb->head) = 0xc0debabe;
- if (skb_is_nonlinear(skb)) {
- printk("Allocated SKB @%p is nonlinear\n");
- }
-#endif
- skb_reserve(skb, 2);
+ if (!adapter->ahw.cut_through)
+ skb_reserve(skb, 2);
/* This will be setup when we receive the
* buffer after it has been filled FSL TBD TBD
* skb->dev = netdev;
*/
- dma = pci_map_single(pdev, skb->data, rcv_desc->dma_size,
+ dma = pci_map_single(pdev, skb->data, rds_ring->dma_size,
PCI_DMA_FROMDEVICE);
pdesc->addr_buffer = cpu_to_le64(dma);
buffer->skb = skb;
buffer->dma = dma;
/* make a rcv descriptor */
pdesc->reference_handle = cpu_to_le16(buffer->ref_handle);
- pdesc->buffer_length = cpu_to_le32(rcv_desc->dma_size);
+ pdesc->buffer_length = cpu_to_le32(rds_ring->dma_size);
DPRINTK(INFO, "done writing descripter\n");
producer =
- get_next_index(producer, rcv_desc->max_rx_desc_count);
- index = get_next_index(index, rcv_desc->max_rx_desc_count);
- buffer = &rcv_desc->rx_buf_arr[index];
+ get_next_index(producer, rds_ring->max_rx_desc_count);
+ index = get_next_index(index, rds_ring->max_rx_desc_count);
}
/* if we did allocate buffers, then write the count to Phantom */
if (count) {
- rcv_desc->begin_alloc = index;
- rcv_desc->rcv_pending += count;
- rcv_desc->producer = producer;
- if (rcv_desc->rcv_free >= 32) {
- rcv_desc->rcv_free = 0;
+ rds_ring->begin_alloc = index;
+ rds_ring->producer = producer;
/* Window = 1 */
- writel((producer - 1) &
- (rcv_desc->max_rx_desc_count - 1),
- NETXEN_CRB_NORMALIZE(adapter,
- recv_crb_registers[
- adapter->portnum].
- rcv_desc_crb[ringid].
- crb_rcv_producer_offset));
+ adapter->pci_write_normalize(adapter,
+ rds_ring->crb_rcv_producer,
+ (producer-1) & (rds_ring->max_rx_desc_count-1));
+
+ if (adapter->fw_major < 4) {
/*
* Write a doorbell msg to tell phanmon of change in
* receive ring producer
+ * Only for firmware version < 4.0.0
*/
netxen_set_msg_peg_id(msg, NETXEN_RCV_PEG_DB_ID);
netxen_set_msg_privid(msg);
netxen_set_msg_count(msg,
((producer -
- 1) & (rcv_desc->
+ 1) & (rds_ring->
max_rx_desc_count - 1)));
netxen_set_msg_ctxid(msg, adapter->portnum);
netxen_set_msg_opcode(msg, NETXEN_RCV_PRODUCER(ringid));
writel(msg,
DB_NORMALIZE(adapter,
NETXEN_RCV_PRODUCER_OFFSET));
- wmb();
}
}
}
static void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter,
uint32_t ctx, uint32_t ringid)
{
- struct pci_dev *pdev = adapter->ahw.pdev;
+ struct pci_dev *pdev = adapter->pdev;
struct sk_buff *skb;
struct netxen_recv_context *recv_ctx = &(adapter->recv_ctx[ctx]);
- struct netxen_rcv_desc_ctx *rcv_desc = NULL;
+ struct nx_host_rds_ring *rds_ring = NULL;
u32 producer;
struct rcv_desc *pdesc;
struct netxen_rx_buffer *buffer;
int count = 0;
int index = 0;
+ struct list_head *head;
- rcv_desc = &recv_ctx->rcv_desc[ringid];
+ rds_ring = &recv_ctx->rds_rings[ringid];
- producer = rcv_desc->producer;
- index = rcv_desc->begin_alloc;
- buffer = &rcv_desc->rx_buf_arr[index];
+ producer = rds_ring->producer;
+ index = rds_ring->begin_alloc;
+ head = &rds_ring->free_list;
/* We can start writing rx descriptors into the phantom memory. */
- while (buffer->state == NETXEN_BUFFER_FREE) {
- skb = dev_alloc_skb(rcv_desc->skb_size);
+ while (!list_empty(head)) {
+
+ skb = dev_alloc_skb(rds_ring->skb_size);
if (unlikely(!skb)) {
- /*
- * We need to schedule the posting of buffers to the pegs.
- */
- rcv_desc->begin_alloc = index;
- DPRINTK(ERR, "netxen_post_rx_buffers_nodb: "
- " allocated only %d buffers\n", count);
+ rds_ring->begin_alloc = index;
break;
}
+
+ buffer = list_entry(head->next, struct netxen_rx_buffer, list);
+ list_del(&buffer->list);
+
count++; /* now there should be no failure */
- pdesc = &rcv_desc->desc_head[producer];
- skb_reserve(skb, 2);
- /*
- * This will be setup when we receive the
- * buffer after it has been filled
- * skb->dev = netdev;
- */
+ pdesc = &rds_ring->desc_head[producer];
+ if (!adapter->ahw.cut_through)
+ skb_reserve(skb, 2);
buffer->skb = skb;
buffer->state = NETXEN_BUFFER_BUSY;
buffer->dma = pci_map_single(pdev, skb->data,
- rcv_desc->dma_size,
+ rds_ring->dma_size,
PCI_DMA_FROMDEVICE);
/* make a rcv descriptor */
pdesc->reference_handle = cpu_to_le16(buffer->ref_handle);
- pdesc->buffer_length = cpu_to_le32(rcv_desc->dma_size);
+ pdesc->buffer_length = cpu_to_le32(rds_ring->dma_size);
pdesc->addr_buffer = cpu_to_le64(buffer->dma);
- DPRINTK(INFO, "done writing descripter\n");
producer =
- get_next_index(producer, rcv_desc->max_rx_desc_count);
- index = get_next_index(index, rcv_desc->max_rx_desc_count);
- buffer = &rcv_desc->rx_buf_arr[index];
+ get_next_index(producer, rds_ring->max_rx_desc_count);
+ index = get_next_index(index, rds_ring->max_rx_desc_count);
+ buffer = &rds_ring->rx_buf_arr[index];
}
/* if we did allocate buffers, then write the count to Phantom */
if (count) {
- rcv_desc->begin_alloc = index;
- rcv_desc->rcv_pending += count;
- rcv_desc->producer = producer;
- if (rcv_desc->rcv_free >= 32) {
- rcv_desc->rcv_free = 0;
+ rds_ring->begin_alloc = index;
+ rds_ring->producer = producer;
/* Window = 1 */
- writel((producer - 1) &
- (rcv_desc->max_rx_desc_count - 1),
- NETXEN_CRB_NORMALIZE(adapter,
- recv_crb_registers[
- adapter->portnum].
- rcv_desc_crb[ringid].
- crb_rcv_producer_offset));
+ adapter->pci_write_normalize(adapter,
+ rds_ring->crb_rcv_producer,
+ (producer-1) & (rds_ring->max_rx_desc_count-1));
wmb();
- }
}
}
-int netxen_nic_tx_has_work(struct netxen_adapter *adapter)
-{
- if (find_diff_among(adapter->last_cmd_consumer,
- adapter->cmd_producer,
- adapter->max_tx_desc_count) > 0)
- return 1;
-
- return 0;
-}
-
-
void netxen_nic_clear_stats(struct netxen_adapter *adapter)
{
memset(&adapter->stats, 0, sizeof(adapter->stats));