⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 defxx.c

📁 powerpc内核mpc8241linux系统下net驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
 *   acknowledges the state change interrupt. * *          INCORRECT                                      CORRECT *      read type 0 int reasons                   read type 0 int reasons *      read adapter state                        ack type 0 interrupts *      ack type 0 interrupts                     read adapter state *      ... process interrupt ...                 ... process interrupt ... * * Return Codes: *   None * * Assumptions: *   None * * Side Effects: *   An adapter reset may occur if the adapter has any Type 0 error interrupts *   or if the port status indicates that the adapter is halted.  The driver *   is responsible for reinitializing the adapter with the current CAM *   contents and adapter filter settings. */void dfx_int_type_0_process(	DFX_board_t	*bp	)	{	PI_UINT32	type_0_status;		/* Host Interrupt Type 0 register */	PI_UINT32	state;				/* current adap state (from port status) */	/*	 * Read host interrupt Type 0 register to determine which Type 0	 * interrupts are pending.  Immediately write it back out to clear	 * those interrupts.	 */	dfx_port_read_long(bp, PI_PDQ_K_REG_TYPE_0_STATUS, &type_0_status);	dfx_port_write_long(bp, PI_PDQ_K_REG_TYPE_0_STATUS, type_0_status);	/* Check for Type 0 error interrupts */	if (type_0_status & (PI_TYPE_0_STAT_M_NXM |							PI_TYPE_0_STAT_M_PM_PAR_ERR |							PI_TYPE_0_STAT_M_BUS_PAR_ERR))		{		/* Check for Non-Existent Memory error */		if (type_0_status & PI_TYPE_0_STAT_M_NXM)			printk("%s: Non-Existent Memory Access Error\n", bp->dev->name);		/* Check for Packet Memory Parity error */		if (type_0_status & PI_TYPE_0_STAT_M_PM_PAR_ERR)			printk("%s: Packet Memory Parity Error\n", bp->dev->name);		/* Check for Host Bus Parity error */		if (type_0_status & PI_TYPE_0_STAT_M_BUS_PAR_ERR)			printk("%s: Host Bus Parity Error\n", bp->dev->name);		/* Reset adapter and bring it back on-line */		bp->link_available = PI_K_FALSE;	/* link is no longer available */		bp->reset_type = 0;					/* rerun on-board diagnostics */		printk("%s: Resetting adapter...\n", bp->dev->name);		if (dfx_adap_init(bp) != DFX_K_SUCCESS)			{			printk("%s: Adapter reset failed!  Disabling adapter interrupts.\n", bp->dev->name);			dfx_port_write_long(bp, PI_PDQ_K_REG_HOST_INT_ENB, PI_HOST_INT_K_DISABLE_ALL_INTS);			return;			}		printk("%s: Adapter reset successful!\n", bp->dev->name);		return;		}	/* Check for transmit flush interrupt */	if (type_0_status & PI_TYPE_0_STAT_M_XMT_FLUSH)		{		/* Flush any pending xmt's and acknowledge the flush interrupt */		bp->link_available = PI_K_FALSE;		/* link is no longer available */		dfx_xmt_flush(bp);						/* flush any outstanding packets */		(void) dfx_hw_port_ctrl_req(bp,									PI_PCTRL_M_XMT_DATA_FLUSH_DONE,									0,									0,									NULL);		}	/* Check for adapter state change */	if (type_0_status & PI_TYPE_0_STAT_M_STATE_CHANGE)		{                     		/* Get latest adapter state */		state = dfx_hw_adap_state_rd(bp);	/* get adapter state */		if (state == PI_STATE_K_HALTED)			{			/*			 * Adapter has transitioned to HALTED state, try to reset			 * adapter to bring it back on-line.  If reset fails,			 * leave the adapter in the broken state.			 */			printk("%s: Controller has transitioned to HALTED state!\n", bp->dev->name);			dfx_int_pr_halt_id(bp);			/* display halt id as string */			/* Reset adapter and bring it back on-line */			bp->link_available = PI_K_FALSE;	/* link is no longer available */			bp->reset_type = 0;					/* rerun on-board diagnostics */			printk("%s: Resetting adapter...\n", bp->dev->name);			if (dfx_adap_init(bp) != DFX_K_SUCCESS)				{				printk("%s: Adapter reset failed!  Disabling adapter interrupts.\n", bp->dev->name);				dfx_port_write_long(bp, PI_PDQ_K_REG_HOST_INT_ENB, PI_HOST_INT_K_DISABLE_ALL_INTS);				return;				}			printk("%s: Adapter reset successful!\n", bp->dev->name);			}		else if (state == PI_STATE_K_LINK_AVAIL)			{			bp->link_available = PI_K_TRUE;		/* set link available flag */			}		}	return;	}/* * ================== * = dfx_int_common = * ================== *    * Overview: *   Interrupt service routine (ISR) *   * Returns: *   None *        * Arguments: *   bp - pointer to board information * * Functional Description: *   This is the ISR which processes incoming adapter interrupts. * * Return Codes: *   None * * Assumptions: *   This routine assumes PDQ interrupts have not been disabled. *   When interrupts are disabled at the PDQ, the Port Status register *   is automatically cleared.  This routine uses the Port Status *   register value to determine whether a Type 0 interrupt occurred, *   so it's important that adapter interrupts are not normally *   enabled/disabled at the PDQ. * *   It's vital that this routine is NOT reentered for the *   same board and that the OS is not in another section of *   code (eg. dfx_xmt_queue_pkt) for the same board on a *   different thread. * * Side Effects: *   Pending interrupts are serviced.  Depending on the type of *   interrupt, acknowledging and clearing the interrupt at the *   PDQ involves writing a register to clear the interrupt bit *   or updating completion indices. */void dfx_int_common(	DFX_board_t	*bp	)	{	PI_UINT32	port_status;		/* Port Status register */	/* Process xmt interrupts - frequent case, so always call this routine */	dfx_xmt_done(bp);				/* free consumed xmt packets */	/* Process rcv interrupts - frequent case, so always call this routine */	dfx_rcv_queue_process(bp);		/* service received LLC frames */	/*	 * Transmit and receive producer and completion indices are updated on the	 * adapter by writing to the Type 2 Producer register.  Since the frequent	 * case is that we'll be processing either LLC transmit or receive buffers,	 * we'll optimize I/O writes by doing a single register write here.	 */	dfx_port_write_long(bp, PI_PDQ_K_REG_TYPE_2_PROD, bp->rcv_xmt_reg.lword);	/* Read PDQ Port Status register to find out which interrupts need processing */	dfx_port_read_long(bp, PI_PDQ_K_REG_PORT_STATUS, &port_status);	/* Process Type 0 interrupts (if any) - infrequent, so only call when needed */	if (port_status & PI_PSTATUS_M_TYPE_0_PENDING)		dfx_int_type_0_process(bp);	/* process Type 0 interrupts */	return;	}/* * ================= * = dfx_interrupt = * ================= *    * Overview: *   Interrupt processing routine *   * Returns: *   None *        * Arguments: *   irq	- interrupt vector *   dev_id	- pointer to device information *	 regs	- pointer to registers structure * * Functional Description: *   This routine calls the interrupt processing routine for this adapter.  It *   disables and reenables adapter interrupts, as appropriate.  We can support *   shared interrupts since the incoming dev_id pointer provides our device *   structure context. * * Return Codes: *   None * * Assumptions: *   The interrupt acknowledgement at the hardware level (eg. ACKing the PIC *   on Intel-based systems) is done by the operating system outside this *   routine. * *	 System interrupts are enabled through this call. * * Side Effects: *   Interrupts are disabled, then reenabled at the adapter. */void dfx_interrupt(	int				irq,	void			*dev_id,	struct pt_regs	*regs	)	{	struct device	*dev = (struct device *) dev_id;	DFX_board_t		*bp;	/* private board structure pointer */	u8				tmp;	/* used for disabling/enabling ints */	/* Get board pointer only if device structure is valid */	if (dev == NULL)		{		printk("dfx_interrupt(): irq %d for unknown device!\n", irq);		return;		}	bp = (DFX_board_t *) dev->priv;	spin_lock(&bp->lock);		/* See if we're already servicing an interrupt */	if (dev->interrupt)		printk("%s: Re-entering the interrupt handler!\n", dev->name);	dev->interrupt = DFX_MASK_INTERRUPTS;	/* ensure non reentrancy */	/* Service adapter interrupts */	if (bp->bus_type == DFX_BUS_TYPE_PCI)		{		/* Disable PDQ-PFI interrupts at PFI */		dfx_port_write_long(bp, PFI_K_REG_MODE_CTRL, PFI_MODE_M_DMA_ENB);		/* Call interrupt service routine for this adapter */		dfx_int_common(bp);		/* Clear PDQ interrupt status bit and reenable interrupts */		dfx_port_write_long(bp, PFI_K_REG_STATUS, PFI_STATUS_M_PDQ_INT);		dfx_port_write_long(bp, PFI_K_REG_MODE_CTRL,					(PFI_MODE_M_PDQ_INT_ENB + PFI_MODE_M_DMA_ENB));		}	else		{		/* Disable interrupts at the ESIC */		dfx_port_read_byte(bp, PI_ESIC_K_IO_CONFIG_STAT_0, &tmp);		tmp &= ~PI_CONFIG_STAT_0_M_INT_ENB;		dfx_port_write_byte(bp, PI_ESIC_K_IO_CONFIG_STAT_0, tmp);		/* Call interrupt service routine for this adapter */		dfx_int_common(bp);		/* Reenable interrupts at the ESIC */		dfx_port_read_byte(bp, PI_ESIC_K_IO_CONFIG_STAT_0, &tmp);		tmp |= PI_CONFIG_STAT_0_M_INT_ENB;		dfx_port_write_byte(bp, PI_ESIC_K_IO_CONFIG_STAT_0, tmp);		}	dev->interrupt = DFX_UNMASK_INTERRUPTS;	spin_unlock(&bp->lock);	return;	}/* * ===================== * = dfx_ctl_get_stats = * ===================== *    * Overview: *   Get statistics for FDDI adapter *   * Returns: *   Pointer to FDDI statistics structure *        * Arguments: *   dev - pointer to device information * * Functional Description: *   Gets current MIB objects from adapter, then *   returns FDDI statistics structure as defined *   in if_fddi.h. * *   Note: Since the FDDI statistics structure is *   still new and the device structure doesn't *   have an FDDI-specific get statistics handler, *   we'll return the FDDI statistics structure as *   a pointer to an Ethernet statistics structure. *   That way, at least the first part of the statistics *   structure can be decoded properly, and it allows *   "smart" applications to perform a second cast to *   decode the FDDI-specific statistics. * *   We'll have to pay attention to this routine as the *   device structure becomes more mature and LAN media *   independent. * * Return Codes: *   None * * Assumptions: *   None * * Side Effects: *   None */struct net_device_stats *dfx_ctl_get_stats(	struct device *dev	)	{	DFX_board_t	*bp = (DFX_board_t *)dev->priv;	/* Fill the bp->stats structure with driver-maintained counters */	bp->stats.rx_packets			= bp->rcv_total_frames;	bp->stats.tx_packets			= bp->xmt_total_frames;	bp->stats.rx_bytes			= bp->rcv_total_bytes;	bp->stats.tx_bytes			= bp->xmt_total_bytes;	bp->stats.rx_errors				= (u32)(bp->rcv_crc_errors + bp->rcv_frame_status_errors + bp->rcv_length_errors);	bp->stats.tx_errors				= bp->xmt_length_errors;	bp->stats.rx_dropped			= bp->rcv_discards;	bp->stats.tx_dropped			= bp->xmt_discards;	bp->stats.multicast				= bp->rcv_multicast_frames;	bp->stats.transmit_collision	= 0;	/* always zero (0) for FDDI */	/* Get FDDI SMT MIB objects */	bp->cmd_req_virt->cmd_type = PI_CMD_K_SMT_MIB_GET;	if (dfx_hw_dma_cmd_req(bp) != DFX_K_SUCCESS)		return((struct net_device_stats *) &bp->stats);	/* Fill the bp->stats structure with the SMT MIB object values */	memcpy(bp->stats.smt_station_id, &bp->cmd_rsp_virt->smt_mib_get.smt_station_id, sizeof(bp->cmd_rsp_virt->smt_mib_get.smt_station_id));	bp->stats.smt_op_version_id					= bp->cmd_rsp_virt->smt_mib_get.smt_op_version_id;	bp->stats.smt_hi_version_id					= bp->cmd_rsp_virt->smt_mib_get.smt_hi_version_id;	bp->stats.smt_lo_version_id					= bp->cmd_rsp_virt->smt_mib_get.smt_lo_version_id;	memcpy(bp->stats.smt_user_data, &bp->cmd_rsp_virt->smt_mib_get.smt_user_data, sizeof(bp->cmd_rsp_virt->smt_mib_get.smt_user_data));	bp->stats.smt_mib_version_id				= bp->cmd_rsp_virt->smt_mib_get.smt_mib_version_id;	bp->stats.smt_mac_cts						= bp->cmd_rsp_virt->smt_mib_get.smt_mac_ct;	bp->stats.smt_non_master_cts				= bp->cmd_rsp_virt->smt_mib_get.smt_non_master_ct;	bp->stats.smt_master_cts					= bp->cmd_rsp_virt->smt_mib_get.smt_master_ct;	bp->stats.smt_available_paths				= bp->cmd_rsp_virt->smt_mib_get.smt_available_paths;	bp->stats.smt_config_capabilities			= bp->cmd_rsp_virt->smt_mib_get.smt_config_capabilities;	bp->stats.smt_config_policy					= bp->cmd_rsp_virt->smt_mib_get.smt_config_policy;	bp->stats.smt_connection_policy				= bp->cmd_rsp_virt->smt_mib_get.smt_connection_policy;	bp->stats.smt_t_notify						= bp->cmd_rsp_virt->smt_mib_get.smt_t_notify;	bp->stats.smt_stat_rpt_policy				= bp->cmd_rsp_virt->smt_mib_get.smt_stat_rpt_policy;	bp->stats.smt_trace_max_expiration			= bp->cmd_rsp_virt->smt_mib_get.smt_trace_max_expiration;	bp->stats.smt_bypass_present				= bp->cmd_rsp_virt->smt_mib_get.smt_bypass_present;	bp->stats.smt_ecm_state						= bp->cmd_rsp_virt->smt_mib_get.smt_ecm_state;	bp->stats.smt_cf_state						= bp->cmd_rsp_virt->smt_mib_get.smt_cf_state;	bp->stats.smt_remote_disconnect_flag		= bp->cmd_rsp_virt->smt_mib_get.smt_remote_disconnect_flag;	bp->stats.smt_station_status				= bp->cmd_rsp_virt->smt_mib_get.smt_station_status;	bp->stats.smt_peer_wrap_flag				= bp->cmd_rsp_virt->smt_mib_get.smt_peer_wrap_flag;	bp->stats.smt_time_stamp					= bp->cmd_rsp_virt->smt_mib_get.smt_msg_time_stamp.ls;	bp->stats.smt_transition_time_stamp			= bp->cmd_rsp_virt->smt_mib_get.smt_transition_time_stamp.ls;	bp->stats.mac_frame_status_functions		= bp->cmd_rsp_virt->smt_mib_get.mac_frame_status_functions;	bp->stats.mac_t_max_capability				= bp->cmd_rsp_virt->smt_mib_get.mac_t_max_capability;	bp->stats.mac_tvx_capability				= bp->cmd_rsp_virt->smt_mib_get.mac_tvx_capability;	bp->stats.mac_available_paths				= bp->cmd_rsp_virt->smt_mib_get.mac_available_paths;	bp->stats.mac_current_path					= bp->cmd_rsp_virt->smt_mib_get.mac_current_path;	memcpy(bp->stats.mac_upstream_nbr, &bp->cmd_rsp_virt->smt_mib_get.mac_u

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -