📄 defxx.c
字号:
int alloc_size; /* total buffer size needed */ char *top_v, *curr_v; /* virtual addrs into memory block */ u32 top_p, curr_p; /* physical addrs into memory block */ u32 data; /* host data register value */ DBG_printk("In dfx_driver_init...\n"); /* Initialize bus-specific hardware registers */ dfx_bus_init(dev); /* * Initialize default values for configurable parameters * * Note: All of these parameters are ones that a user may * want to customize. It'd be nice to break these * out into Space.c or someplace else that's more * accessible/understandable than this file. */ bp->full_duplex_enb = PI_SNMP_K_FALSE; bp->req_ttrt = 8 * 12500; /* 8ms in 80 nanosec units */ bp->burst_size = PI_PDATA_B_DMA_BURST_SIZE_DEF; bp->rcv_bufs_to_post = RCV_BUFS_DEF; /* * Ensure that HW configuration is OK * * Note: Depending on the hardware revision, we may need to modify * some of the configurable parameters to workaround hardware * limitations. We'll perform this configuration check AFTER * setting the parameters to their default values. */ dfx_bus_config_check(bp); /* Disable PDQ interrupts first */ dfx_port_write_long(bp, PI_PDQ_K_REG_HOST_INT_ENB, PI_HOST_INT_K_DISABLE_ALL_INTS); /* Place adapter in DMA_UNAVAILABLE state by resetting adapter */ (void) dfx_hw_dma_uninit(bp, PI_PDATA_A_RESET_M_SKIP_ST); /* Read the factory MAC address from the adapter then save it */ if (dfx_hw_port_ctrl_req(bp, PI_PCTRL_M_MLA, PI_PDATA_A_MLA_K_LO, 0, &data) != DFX_K_SUCCESS) { printk("%s: Could not read adapter factory MAC address!\n", dev->name); return(DFX_K_FAILURE); } memcpy(&bp->factory_mac_addr[0], &data, sizeof(u32)); if (dfx_hw_port_ctrl_req(bp, PI_PCTRL_M_MLA, PI_PDATA_A_MLA_K_HI, 0, &data) != DFX_K_SUCCESS) { printk("%s: Could not read adapter factory MAC address!\n", dev->name); return(DFX_K_FAILURE); } memcpy(&bp->factory_mac_addr[4], &data, sizeof(u16)); /* * Set current address to factory address * * Note: Node address override support is handled through * dfx_ctl_set_mac_address. */ memcpy(dev->dev_addr, bp->factory_mac_addr, FDDI_K_ALEN); if (bp->bus_type == DFX_BUS_TYPE_EISA) printk("%s: DEFEA at I/O addr = 0x%lX, IRQ = %d, Hardware addr = %02X-%02X-%02X-%02X-%02X-%02X\n", dev->name, dev->base_addr, dev->irq, dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); else printk("%s: DEFPA at I/O addr = 0x%lX, IRQ = %d, Hardware addr = %02X-%02X-%02X-%02X-%02X-%02X\n", dev->name, dev->base_addr, dev->irq, dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); /* * Get memory for descriptor block, consumer block, and other buffers * that need to be DMA read or written to by the adapter. */ alloc_size = sizeof(PI_DESCR_BLOCK) + PI_CMD_REQ_K_SIZE_MAX + PI_CMD_RSP_K_SIZE_MAX +#ifndef DYNAMIC_BUFFERS (bp->rcv_bufs_to_post * PI_RCV_DATA_K_SIZE_MAX) +#endif sizeof(PI_CONSUMER_BLOCK) + (PI_ALIGN_K_DESC_BLK - 1); bp->kmalloced = top_v = (char *) kmalloc(alloc_size, GFP_KERNEL); if (top_v == NULL) { printk("%s: Could not allocate memory for host buffers and structures!\n", dev->name); return(DFX_K_FAILURE); } memset(top_v, 0, alloc_size); /* zero out memory before continuing */ top_p = virt_to_bus(top_v); /* get physical address of buffer */ /* * To guarantee the 8K alignment required for the descriptor block, 8K - 1 * plus the amount of memory needed was allocated. The physical address * is now 8K aligned. By carving up the memory in a specific order, * we'll guarantee the alignment requirements for all other structures. * * Note: If the assumptions change regarding the non-paged, non-cached, * physically contiguous nature of the memory block or the address * alignments, then we'll need to implement a different algorithm * for allocating the needed memory. */ curr_p = (u32) (ALIGN(top_p, PI_ALIGN_K_DESC_BLK)); curr_v = top_v + (curr_p - top_p); /* Reserve space for descriptor block */ bp->descr_block_virt = (PI_DESCR_BLOCK *) curr_v; bp->descr_block_phys = curr_p; curr_v += sizeof(PI_DESCR_BLOCK); curr_p += sizeof(PI_DESCR_BLOCK); /* Reserve space for command request buffer */ bp->cmd_req_virt = (PI_DMA_CMD_REQ *) curr_v; bp->cmd_req_phys = curr_p; curr_v += PI_CMD_REQ_K_SIZE_MAX; curr_p += PI_CMD_REQ_K_SIZE_MAX; /* Reserve space for command response buffer */ bp->cmd_rsp_virt = (PI_DMA_CMD_RSP *) curr_v; bp->cmd_rsp_phys = curr_p; curr_v += PI_CMD_RSP_K_SIZE_MAX; curr_p += PI_CMD_RSP_K_SIZE_MAX; /* Reserve space for the LLC host receive queue buffers */ bp->rcv_block_virt = curr_v; bp->rcv_block_phys = curr_p;#ifndef DYNAMIC_BUFFERS curr_v += (bp->rcv_bufs_to_post * PI_RCV_DATA_K_SIZE_MAX); curr_p += (bp->rcv_bufs_to_post * PI_RCV_DATA_K_SIZE_MAX);#endif /* Reserve space for the consumer block */ bp->cons_block_virt = (PI_CONSUMER_BLOCK *) curr_v; bp->cons_block_phys = curr_p; /* Display virtual and physical addresses if debug driver */ DBG_printk("%s: Descriptor block virt = %0lX, phys = %0X\n", dev->name, (long)bp->descr_block_virt, bp->descr_block_phys); DBG_printk("%s: Command Request buffer virt = %0lX, phys = %0X\n", dev->name, (long)bp->cmd_req_virt, bp->cmd_req_phys); DBG_printk("%s: Command Response buffer virt = %0lX, phys = %0X\n", dev->name, (long)bp->cmd_rsp_virt, bp->cmd_rsp_phys); DBG_printk("%s: Receive buffer block virt = %0lX, phys = %0X\n", dev->name, (long)bp->rcv_block_virt, bp->rcv_block_phys); DBG_printk("%s: Consumer block virt = %0lX, phys = %0X\n", dev->name, (long)bp->cons_block_virt, bp->cons_block_phys); return(DFX_K_SUCCESS); }/* * ================= * = dfx_adap_init = * ================= * * Overview: * Brings the adapter to the link avail/link unavailable state. * * Returns: * Condition code * * Arguments: * bp - pointer to board information * * Functional Description: * Issues the low-level firmware/hardware calls necessary to bring * the adapter up, or to properly reset and restore adapter during * run-time. * * Return Codes: * DFX_K_SUCCESS - Adapter brought up successfully * DFX_K_FAILURE - Adapter initialization failed * * Assumptions: * bp->reset_type should be set to a valid reset type value before * calling this routine. * * Side Effects: * Adapter should be in LINK_AVAILABLE or LINK_UNAVAILABLE state * upon a successful return of this routine. */static int dfx_adap_init(DFX_board_t *bp) { DBG_printk("In dfx_adap_init...\n"); /* Disable PDQ interrupts first */ dfx_port_write_long(bp, PI_PDQ_K_REG_HOST_INT_ENB, PI_HOST_INT_K_DISABLE_ALL_INTS); /* Place adapter in DMA_UNAVAILABLE state by resetting adapter */ if (dfx_hw_dma_uninit(bp, bp->reset_type) != DFX_K_SUCCESS) { printk("%s: Could not uninitialize/reset adapter!\n", bp->dev->name); return(DFX_K_FAILURE); } /* * When the PDQ is reset, some false Type 0 interrupts may be pending, * so we'll acknowledge all Type 0 interrupts now before continuing. */ dfx_port_write_long(bp, PI_PDQ_K_REG_TYPE_0_STATUS, PI_HOST_INT_K_ACK_ALL_TYPE_0); /* * Clear Type 1 and Type 2 registers before going to DMA_AVAILABLE state * * Note: We only need to clear host copies of these registers. The PDQ reset * takes care of the on-board register values. */ bp->cmd_req_reg.lword = 0; bp->cmd_rsp_reg.lword = 0; bp->rcv_xmt_reg.lword = 0; /* Clear consumer block before going to DMA_AVAILABLE state */ memset(bp->cons_block_virt, 0, sizeof(PI_CONSUMER_BLOCK)); /* Initialize the DMA Burst Size */ if (dfx_hw_port_ctrl_req(bp, PI_PCTRL_M_SUB_CMD, PI_SUB_CMD_K_BURST_SIZE_SET, bp->burst_size, NULL) != DFX_K_SUCCESS) { printk("%s: Could not set adapter burst size!\n", bp->dev->name); return(DFX_K_FAILURE); } /* * Set base address of Consumer Block * * Assumption: 32-bit physical address of consumer block is 64 byte * aligned. That is, bits 0-5 of the address must be zero. */ if (dfx_hw_port_ctrl_req(bp, PI_PCTRL_M_CONS_BLOCK, bp->cons_block_phys, 0, NULL) != DFX_K_SUCCESS) { printk("%s: Could not set consumer block address!\n", bp->dev->name); return(DFX_K_FAILURE); } /* * Set base address of Descriptor Block and bring adapter to DMA_AVAILABLE state * * Note: We also set the literal and data swapping requirements in this * command. Since this driver presently runs on Intel platforms * which are Little Endian, we'll tell the adapter to byte swap * data only. This code will need to change when we support * Big Endian systems (eg. PowerPC). * * Assumption: 32-bit physical address of descriptor block is 8Kbyte * aligned. That is, bits 0-12 of the address must be zero. */ if (dfx_hw_port_ctrl_req(bp, PI_PCTRL_M_INIT, (u32) (bp->descr_block_phys | PI_PDATA_A_INIT_M_BSWAP_DATA), 0, NULL) != DFX_K_SUCCESS) { printk("%s: Could not set descriptor block address!\n", bp->dev->name); return(DFX_K_FAILURE); } /* Set transmit flush timeout value */ bp->cmd_req_virt->cmd_type = PI_CMD_K_CHARS_SET; bp->cmd_req_virt->char_set.item[0].item_code = PI_ITEM_K_FLUSH_TIME; bp->cmd_req_virt->char_set.item[0].value = 3; /* 3 seconds */ bp->cmd_req_virt->char_set.item[0].item_index = 0; bp->cmd_req_virt->char_set.item[1].item_code = PI_ITEM_K_EOL; if (dfx_hw_dma_cmd_req(bp) != DFX_K_SUCCESS) { printk("%s: DMA command request failed!\n", bp->dev->name); return(DFX_K_FAILURE); } /* Set the initial values for eFDXEnable and MACTReq MIB objects */ bp->cmd_req_virt->cmd_type = PI_CMD_K_SNMP_SET; bp->cmd_req_virt->snmp_set.item[0].item_code = PI_ITEM_K_FDX_ENB_DIS; bp->cmd_req_virt->snmp_set.item[0].value = bp->full_duplex_enb; bp->cmd_req_virt->snmp_set.item[0].item_index = 0; bp->cmd_req_virt->snmp_set.item[1].item_code = PI_ITEM_K_MAC_T_REQ; bp->cmd_req_virt->snmp_set.item[1].value = bp->req_ttrt; bp->cmd_req_virt->snmp_set.item[1].item_index = 0; bp->cmd_req_virt->snmp_set.item[2].item_code = PI_ITEM_K_EOL; if (dfx_hw_dma_cmd_req(bp) != DFX_K_SUCCESS) { printk("%s: DMA command request failed!\n", bp->dev->name); return(DFX_K_FAILURE); } /* Initialize adapter CAM */ if (dfx_ctl_update_cam(bp) != DFX_K_SUCCESS) { printk("%s: Adapter CAM update failed!\n", bp->dev->name); return(DFX_K_FAILURE); } /* Initialize adapter filters */ if (dfx_ctl_update_filters(bp) != DFX_K_SUCCESS) { printk("%s: Adapter filters update failed!\n", bp->dev->name); return(DFX_K_FAILURE); } /* Initialize receive descriptor block and produce buffers */ dfx_rcv_init(bp); /* Issue START command and bring adapter to LINK_(UN)AVAILABLE state */ bp->cmd_req_virt->cmd_type = PI_CMD_K_START; if (dfx_hw_dma_cmd_req(bp) != DFX_K_SUCCESS) { printk("%s: Start command failed\n", bp->dev->name); return(DFX_K_FAILURE); } /* Initialization succeeded, reenable PDQ interrupts */ dfx_port_write_long(bp, PI_PDQ_K_REG_HOST_INT_ENB, PI_HOST_INT_K_ENABLE_DEF_INTS); return(DFX_K_SUCCESS); }/* * ============ * = dfx_open = * ============ * * Overview: * Opens the adapter * * Returns: * Condition code * * Arguments: * dev - pointer to device information * * Functional Description: * This function brings the adapter to an operational state. * * Return Codes: * 0 - Adapter was successfully opened * -EAGAIN - Could not register IRQ or adapter initialization failed
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -