📄 defxx.c
字号:
/* 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 * * Assumptions: * This routine should only be called for a device that was * initialized successfully during the dfx_probe process. * * Side Effects: * Adapter should be in LINK_AVAILABLE or LINK_UNAVAILABLE state * if the open is successful. */int dfx_open( struct device *dev ) { DFX_board_t *bp = (DFX_board_t *)dev->priv; DBG_printk("In dfx_open...\n"); /* Register IRQ - support shared interrupts by passing device ptr */ if (request_irq(dev->irq, (void *)dfx_interrupt, SA_SHIRQ, dev->name, dev)) { printk("%s: Requested IRQ %d is busy\n", dev->name, dev->irq); return(-EAGAIN); } /* * Set current address to factory MAC address * * Note: We've already done this step in dfx_driver_init. * However, it's possible that a user has set a node * address override, then closed and reopened the * adapter. Unless we reset the device address field * now, we'll continue to use the existing modified * address. */ memcpy(dev->dev_addr, bp->factory_mac_addr, FDDI_K_ALEN); /* Clear local unicast/multicast address tables and counts */ memset(bp->uc_table, 0, sizeof(bp->uc_table)); memset(bp->mc_table, 0, sizeof(bp->mc_table)); bp->uc_count = 0; bp->mc_count = 0; /* Disable promiscuous filter settings */ bp->ind_group_prom = PI_FSTATE_K_BLOCK; bp->group_prom = PI_FSTATE_K_BLOCK; /* Reset and initialize adapter */ bp->reset_type = PI_PDATA_A_RESET_M_SKIP_ST; /* skip self-test */ if (dfx_adap_init(bp) != DFX_K_SUCCESS) { printk("%s: Adapter open failed!\n", dev->name); return(-EAGAIN); } /* Set device structure info */ dev->tbusy = 0; dev->interrupt = DFX_UNMASK_INTERRUPTS; dev->start = 1; return(0); }/* * ============= * = dfx_close = * ============= * * Overview: * Closes the device/module. * * Returns: * Condition code * * Arguments: * dev - pointer to device information * * Functional Description: * This routine closes the adapter and brings it to a safe state. * The interrupt service routine is deregistered with the OS. * The adapter can be opened again with another call to dfx_open(). * * Return Codes: * Always return 0. * * Assumptions: * No further requests for this adapter are made after this routine is * called. dfx_open() can be called to reset and reinitialize the * adapter. * * Side Effects: * Adapter should be in DMA_UNAVAILABLE state upon completion of this * routine. */int dfx_close( struct device *dev ) { DFX_board_t *bp = (DFX_board_t *)dev->priv; DBG_printk("In dfx_close...\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 */ (void) dfx_hw_dma_uninit(bp, PI_PDATA_A_RESET_M_SKIP_ST); /* * Flush any pending transmit buffers * * Note: It's important that we flush the transmit buffers * BEFORE we clear our copy of the Type 2 register. * Otherwise, we'll have no idea how many buffers * we need to free. */ dfx_xmt_flush(bp); /* * Clear Type 1 and Type 2 registers after adapter reset * * Note: Even though we're closing the adapter, it's * possible that an interrupt will occur after * dfx_close is called. Without some assurance to * the contrary we want to make sure that we don't * process receive and transmit LLC frames and update * the Type 2 register with bad information. */ bp->cmd_req_reg.lword = 0; bp->cmd_rsp_reg.lword = 0; bp->rcv_xmt_reg.lword = 0; /* Clear consumer block for the same reason given above */ memset(bp->cons_block_virt, 0, sizeof(PI_CONSUMER_BLOCK)); /* Clear device structure flags */ dev->start = 0; dev->tbusy = 1; /* Deregister (free) IRQ */ free_irq(dev->irq, dev); return(0); }/* * ====================== * = dfx_int_pr_halt_id = * ====================== * * Overview: * Displays halt id's in string form. * * Returns: * None * * Arguments: * bp - pointer to board information * * Functional Description: * Determine current halt id and display appropriate string. * * Return Codes: * None * * Assumptions: * None * * Side Effects: * None */void dfx_int_pr_halt_id( DFX_board_t *bp ) { PI_UINT32 port_status; /* PDQ port status register value */ PI_UINT32 halt_id; /* PDQ port status halt ID */ /* Read the latest port status */ dfx_port_read_long(bp, PI_PDQ_K_REG_PORT_STATUS, &port_status); /* Display halt state transition information */ halt_id = (port_status & PI_PSTATUS_M_HALT_ID) >> PI_PSTATUS_V_HALT_ID; switch (halt_id) { case PI_HALT_ID_K_SELFTEST_TIMEOUT: printk("%s: Halt ID: Selftest Timeout\n", bp->dev->name); break; case PI_HALT_ID_K_PARITY_ERROR: printk("%s: Halt ID: Host Bus Parity Error\n", bp->dev->name); break; case PI_HALT_ID_K_HOST_DIR_HALT: printk("%s: Halt ID: Host-Directed Halt\n", bp->dev->name); break; case PI_HALT_ID_K_SW_FAULT: printk("%s: Halt ID: Adapter Software Fault\n", bp->dev->name); break; case PI_HALT_ID_K_HW_FAULT: printk("%s: Halt ID: Adapter Hardware Fault\n", bp->dev->name); break; case PI_HALT_ID_K_PC_TRACE: printk("%s: Halt ID: FDDI Network PC Trace Path Test\n", bp->dev->name); break; case PI_HALT_ID_K_DMA_ERROR: printk("%s: Halt ID: Adapter DMA Error\n", bp->dev->name); break; case PI_HALT_ID_K_IMAGE_CRC_ERROR: printk("%s: Halt ID: Firmware Image CRC Error\n", bp->dev->name); break; case PI_HALT_ID_K_BUS_EXCEPTION: printk("%s: Halt ID: 68000 Bus Exception\n", bp->dev->name); break; default: printk("%s: Halt ID: Unknown (code = %X)\n", bp->dev->name, halt_id); break; } return; }/* * ========================== * = dfx_int_type_0_process = * ========================== * * Overview: * Processes Type 0 interrupts. * * Returns: * None * * Arguments: * bp - pointer to board information * * Functional Description: * Processes all enabled Type 0 interrupts. If the reason for the interrupt * is a serious fault on the adapter, then an error message is displayed * and the adapter is reset. * * One tricky potential timing window is the rapid succession of "link avail" * "link unavail" state change interrupts. The acknowledgement of the Type 0 * interrupt must be done before reading the state from the Port Status * register. This is true because a state change could occur after reading * the data, but before acknowledging the interrupt. If this state change * does happen, it would be lost because the driver is using the old state, * and it will never know about the new state because it subsequently
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -