netxen_nic_init.c
来自「linux 内核源代码」· C语言 代码 · 共 1,553 行 · 第 1/3 页
C
1,553 行
return ret; } else { printk(KERN_INFO "Data write did not " "succeed at address 0x%x\n", addridx); break; } } } bytes += 4; addridx += 4; } return ret;}int netxen_rom_fast_write_words(struct netxen_adapter *adapter, int addr, u8 *bytes, size_t size){ int ret = 0; ret = rom_lock(adapter); if (ret < 0) return ret; ret = do_rom_fast_write_words(adapter, addr, bytes, size); netxen_rom_unlock(adapter); return ret;}int netxen_rom_wrsr(struct netxen_adapter *adapter, int data){ int ret; ret = netxen_rom_wren(adapter); if (ret < 0) return ret; netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_ROM_WDATA, data); netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE, 0x1); ret = netxen_wait_rom_done(adapter); if (ret < 0) return ret; return netxen_rom_wip_poll(adapter);}int netxen_rom_rdsr(struct netxen_adapter *adapter){ int ret; ret = rom_lock(adapter); if (ret < 0) return ret; ret = netxen_do_rom_rdsr(adapter); netxen_rom_unlock(adapter); return ret;}int netxen_backup_crbinit(struct netxen_adapter *adapter){ int ret = FLASH_SUCCESS; int val; char *buffer = kmalloc(NETXEN_FLASH_SECTOR_SIZE, GFP_KERNEL); if (!buffer) return -ENOMEM; /* unlock sector 63 */ val = netxen_rom_rdsr(adapter); val = val & 0xe3; ret = netxen_rom_wrsr(adapter, val); if (ret != FLASH_SUCCESS) goto out_kfree; ret = netxen_rom_wip_poll(adapter); if (ret != FLASH_SUCCESS) goto out_kfree; /* copy sector 0 to sector 63 */ 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, buffer, NETXEN_FLASH_SECTOR_SIZE); if (ret != FLASH_SUCCESS) goto out_kfree; /* lock sector 63 */ val = netxen_rom_rdsr(adapter); if (!(val & 0x8)) { val |= (0x1 << 2); /* lock sector 63 */ if (netxen_rom_wrsr(adapter, val) == 0) { ret = netxen_rom_wip_poll(adapter); if (ret != FLASH_SUCCESS) goto out_kfree; /* lock SR writes */ ret = netxen_rom_wip_poll(adapter); if (ret != FLASH_SUCCESS) goto out_kfree; } }out_kfree: kfree(buffer); return ret;}int netxen_do_rom_se(struct netxen_adapter *adapter, int addr){ netxen_rom_wren(adapter); netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr); netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3); netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE, M25P_INSTR_SE); if (netxen_wait_rom_done(adapter)) { netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0); return -1; } return netxen_rom_wip_poll(adapter);}void check_erased_flash(struct netxen_adapter *adapter, int addr){ int i; int val; int count = 0, erased_errors = 0; int range; 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) erased_errors++; count++; } if (erased_errors) printk(KERN_INFO "0x%x out of 0x%x words fail to be erased " "for sector address: %x\n", erased_errors, count, addr);}int netxen_rom_se(struct netxen_adapter *adapter, int addr){ int ret = 0; if (rom_lock(adapter) != 0) { return -1; } ret = netxen_do_rom_se(adapter, addr); netxen_rom_unlock(adapter); msleep(30); check_erased_flash(adapter, addr); return ret;}intnetxen_flash_erase_sections(struct netxen_adapter *adapter, int start, int end){ int ret = FLASH_SUCCESS; int i; for (i = start; i < end; i++) { ret = netxen_rom_se(adapter, i * NETXEN_FLASH_SECTOR_SIZE); if (ret) break; ret = netxen_rom_wip_poll(adapter); if (ret < 0) return ret; } return ret;}intnetxen_flash_erase_secondary(struct netxen_adapter *adapter){ int ret = FLASH_SUCCESS; int start, end; start = NETXEN_SECONDARY_START / NETXEN_FLASH_SECTOR_SIZE; end = NETXEN_USER_START / NETXEN_FLASH_SECTOR_SIZE; ret = netxen_flash_erase_sections(adapter, start, end); return ret;}intnetxen_flash_erase_primary(struct netxen_adapter *adapter){ int ret = FLASH_SUCCESS; int start, end; start = NETXEN_PRIMARY_START / NETXEN_FLASH_SECTOR_SIZE; end = NETXEN_SECONDARY_START / NETXEN_FLASH_SECTOR_SIZE; ret = netxen_flash_erase_sections(adapter, start, end); return ret;}void netxen_halt_pegs(struct netxen_adapter *adapter){ netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_0 + 0x3c, 1); netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_1 + 0x3c, 1); netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_2 + 0x3c, 1); netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_3 + 0x3c, 1);}int netxen_flash_unlock(struct netxen_adapter *adapter){ int ret = 0; ret = netxen_rom_wrsr(adapter, 0); if (ret < 0) return ret; ret = netxen_rom_wren(adapter); if (ret < 0) return ret; return ret;}#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 0x400int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose){ int addr, val, status; int n, i; int init_delay = 0; struct crb_addr_pair *buf; 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); 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 board type\n"); if (netxen_rom_fast_read(adapter, NETXEN_BOARDNUM, &val) == 0) printk("P2 ROM board num: 0x%08x\n", val); else printk("Could not read board number\n"); if (netxen_rom_fast_read(adapter, NETXEN_CHIPNUM, &val) == 0) printk("P2 ROM chip num: 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); 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); } 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", buf[i].addr); continue; } off += NETXEN_PCI_CRBSPACE; /* skipping cold reboot MAGIC */ if (off == NETXEN_CAM_RAM(0x1fc)) 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; /* 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)); netxen_nic_pci_change_crbwindow(adapter, 1); } if (init_delay == 1) { msleep(2000); init_delay = 0; } msleep(20); } kfree(buf); /* 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 */ 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;}int netxen_initialize_adapter_offload(struct netxen_adapter *adapter){ uint64_t addr; uint32_t hi; uint32_t lo; adapter->dummy_dma.addr = pci_alloc_consistent(adapter->ahw.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__); return -ENOMEM; } addr = (uint64_t) adapter->dummy_dma.phys_addr; 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)); return 0;}void netxen_free_adapter_offload(struct netxen_adapter *adapter){ if (adapter->dummy_dma.addr) { pci_free_consistent(adapter->ahw.pdev, NETXEN_HOST_DUMMY_DMA_SIZE, adapter->dummy_dma.addr, adapter->dummy_dma.phys_addr); adapter->dummy_dma.addr = NULL; }}int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val){ u32 val = 0; int retries = 30; 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)); 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; } } return 0;}int netxen_nic_rx_has_work(struct netxen_adapter *adapter){ int ctx; 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; consumer = recv_ctx->status_rx_consumer; desc_head = recv_ctx->rcv_status_desc_head; desc = &desc_head[consumer]; if (netxen_get_sts_owner(desc) & STATUS_OWNER_HOST) return 1; } return 0;}static inline int netxen_nic_check_temp(struct netxen_adapter *adapter){ 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;}void netxen_watchdog_task(struct work_struct *work){ struct net_device *netdev; struct netxen_adapter *adapter =
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?