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

📄 ibmtr.c

📁 powerpc内核mpc8241linux系统下net驱动程序
💻 C
📖 第 1 页 / 共 4 页
字号:
			DPRINTK("8 reason bytes follow: ");			for(i=0; i<8; i++, check_reason++)				printk("%02X ", (int)readb(check_reason));			printk("\n");			writeb((~ADAP_CHK_INT), ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);			writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET  + ISRP_EVEN);			dev->interrupt=0;		} else if (readb(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN)				 & (TCR_INT | ERR_INT | ACCESS_INT)) {			DPRINTK("adapter error: ISRP_EVEN : %02x\n",				(int)readb(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN));			writeb(~(TCR_INT | ERR_INT | ACCESS_INT),			       ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN);			writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET  + ISRP_EVEN);			dev->interrupt=0;		} else if (status			   & (SRB_RESP_INT | ASB_FREE_INT | ARB_CMD_INT | SSB_RESP_INT)) {			/* SRB, ASB, ARB or SSB response */			if (status & SRB_RESP_INT) { /* SRB response */				switch(readb(ti->srb)) { /* SRB command check */				      case XMIT_DIR_FRAME: {					      unsigned char xmit_ret_code;					      xmit_ret_code=readb(ti->srb + offsetof(struct srb_xmit, ret_code));					      if (xmit_ret_code != 0xff) {						      DPRINTK("error on xmit_dir_frame request: %02X\n",							      xmit_ret_code);						      if (ti->current_skb) {							      dev_kfree_skb(ti->current_skb);							      ti->current_skb=NULL;						      }						      dev->tbusy=0;						      if (ti->readlog_pending) ibmtr_readlog(dev);					      }				      }				      break;				      case XMIT_UI_FRAME: {					      unsigned char xmit_ret_code;					      xmit_ret_code=readb(ti->srb + offsetof(struct srb_xmit, ret_code));					      if (xmit_ret_code != 0xff) {						      DPRINTK("error on xmit_ui_frame request: %02X\n",							      xmit_ret_code);						      if (ti->current_skb) {							      dev_kfree_skb(ti->current_skb);							      ti->current_skb=NULL;						      }						      dev->tbusy=0;						      if (ti->readlog_pending) ibmtr_readlog(dev);					      }				      }				      break;				      case DIR_OPEN_ADAPTER: {					      unsigned char open_ret_code;					      __u16 open_error_code;					      ti->srb=ti->sram+ntohs(readw(ti->init_srb +offsetof(struct srb_open_response, srb_addr)));					      ti->ssb=ti->sram+ntohs(readw(ti->init_srb +offsetof(struct srb_open_response, ssb_addr)));					      ti->arb=ti->sram+ntohs(readw(ti->init_srb +offsetof(struct srb_open_response, arb_addr)));					      ti->asb=ti->sram+ntohs(readw(ti->init_srb +offsetof(struct srb_open_response, asb_addr)));					      ti->current_skb=NULL;					      open_ret_code = readb(ti->init_srb +offsetof(struct srb_open_response, ret_code));					      open_error_code = ntohs(readw(ti->init_srb +offsetof(struct srb_open_response, error_code)));					      if (open_ret_code==7) {						      if (!ti->auto_ringspeedsave && (open_error_code==0x24)) {							      DPRINTK("Open failed: Adapter speed must match ring "								      "speed if Automatic Ring Speed Save is disabled.\n");							      ti->open_status=FAILURE;							      wake_up(&ti->wait_for_reset);						      } else if (open_error_code==0x24)							      DPRINTK("Retrying open to adjust to ring speed.\n");						      else if ((open_error_code==0x2d) && ti->auto_ringspeedsave)							      DPRINTK("No signal detected for Auto Speed Detection.\n");						      else if (open_error_code==0x11)						      {							      if (ti->retry_count--) 								      DPRINTK("Ring broken/disconnected, retrying...\n");							      else {								      DPRINTK("Ring broken/disconnected, open failed.\n");								      ti->open_status = FAILURE;							      }						      }						      else DPRINTK("Unrecoverable error: error code = %04x.\n",								   open_error_code);					      } else if (!open_ret_code) {#if !TR_NEWFORMAT						      DPRINTK("board opened...\n");#else						      DPRINTK("Adapter initialized and opened.\n");#endif						      writeb(~(SRB_RESP_INT),							     ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);						      writeb(~(CMD_IN_SRB),							     ti->mmio + ACA_OFFSET + ACA_RESET + ISRA_ODD);						      open_sap(EXTENDED_SAP,dev);						      /* YdW probably hates me */						      goto skip_reset;					      } else						      DPRINTK("open failed: ret_code = %02X, retrying\n",							      open_ret_code);					      if (ti->open_status != FAILURE) {						      ibmtr_reset_timer(&(ti->tr_timer), dev);					      }				      }				      break;				      case DIR_CLOSE_ADAPTER:					wake_up(&ti->wait_for_tok_int);					break;				      case DLC_OPEN_SAP:					if (readb(ti->srb+offsetof(struct dlc_open_sap, ret_code))) {						DPRINTK("open_sap failed: ret_code = %02X,retrying\n",							(int)readb(ti->srb+offsetof(struct dlc_open_sap, ret_code)));						ibmtr_reset_timer(&(ti->tr_timer), dev);					} else {						ti->exsap_station_id=							readw(ti->srb+offsetof(struct dlc_open_sap, station_id));						ti->open_status=SUCCESS; /* TR adapter is now available */						wake_up(&ti->wait_for_reset);					}					break;				      case DIR_INTERRUPT:				      case DIR_MOD_OPEN_PARAMS:				      case DIR_SET_GRP_ADDR:				      case DIR_SET_FUNC_ADDR:				      case DLC_CLOSE_SAP:					if (readb(ti->srb+offsetof(struct srb_interrupt, ret_code)))						DPRINTK("error on %02X: %02X\n",							(int)readb(ti->srb+offsetof(struct srb_interrupt, command)),							(int)readb(ti->srb+offsetof(struct srb_interrupt, ret_code)));					break;				      case DIR_READ_LOG:					if (readb(ti->srb+offsetof(struct srb_read_log, ret_code)))						DPRINTK("error on dir_read_log: %02X\n",							(int)readb(ti->srb+offsetof(struct srb_read_log, ret_code)));					else					    if (IBMTR_DEBUG_MESSAGES) {						DPRINTK(							"Line errors %02X, Internal errors %02X, Burst errors %02X\n"							"A/C errors %02X, Abort delimiters %02X, Lost frames %02X\n"							"Receive congestion count %02X, Frame copied errors %02X\n"							"Frequency errors %02X, Token errors %02X\n",							(int)readb(ti->srb+offsetof(struct srb_read_log,										    line_errors)),							(int)readb(ti->srb+offsetof(struct srb_read_log,										    internal_errors)),							(int)readb(ti->srb+offsetof(struct srb_read_log,										    burst_errors)),							(int)readb(ti->srb+offsetof(struct srb_read_log, A_C_errors)),							(int)readb(ti->srb+offsetof(struct srb_read_log,										    abort_delimiters)),							(int)readb(ti->srb+offsetof(struct srb_read_log,										    lost_frames)),							(int)readb(ti->srb+offsetof(struct srb_read_log,												    recv_congest_count)),							(int)readb(ti->srb+offsetof(struct srb_read_log,										    frame_copied_errors)),							(int)readb(ti->srb+offsetof(struct srb_read_log,										    frequency_errors)),							(int)readb(ti->srb+offsetof(struct srb_read_log,												    token_errors)));					    }					dev->tbusy=0;					break;				      default:					DPRINTK("Unknown command %02X encountered\n",						(int)readb(ti->srb));				} /* SRB command check */				writeb(~CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_RESET + ISRA_ODD);				writeb(~SRB_RESP_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);			  skip_reset:			} /* SRB response */			if (status & ASB_FREE_INT) { /* ASB response */				switch(readb(ti->asb)) { /* ASB command check */				      case REC_DATA:				      case XMIT_UI_FRAME:				      case XMIT_DIR_FRAME:					break;				      default:					DPRINTK("unknown command in asb %02X\n",						(int)readb(ti->asb));				} /* ASB command check */				if (readb(ti->asb+2)!=0xff) /* checks ret_code */				    DPRINTK("ASB error %02X in cmd %02X\n",					    (int)readb(ti->asb+2),(int)readb(ti->asb));				writeb(~ASB_FREE_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);			} /* ASB response */			if (status & ARB_CMD_INT) { /* ARB response */				switch (readb(ti->arb)) { /* ARB command check */				      case DLC_STATUS:					DPRINTK("DLC_STATUS new status: %02X on station %02X\n",						ntohs(readw(ti->arb + offsetof(struct arb_dlc_status, status))),						ntohs(readw(ti->arb									    +offsetof(struct arb_dlc_status, station_id))));					break;				      case REC_DATA:					tr_rx(dev);					break;				      case RING_STAT_CHANGE: {					      unsigned short ring_status;					      ring_status=ntohs(readw(ti->arb								      +offsetof(struct arb_ring_stat_change, ring_status)));					      if (ring_status & (SIGNAL_LOSS | LOBE_FAULT)) {						      DPRINTK("Signal loss/Lobe fault\n");						      DPRINTK("We try to reopen the adapter.\n");						      ibmtr_reset_timer(&(ti->tr_timer), dev);					      } else if (ring_status & (HARD_ERROR | XMIT_BEACON											| AUTO_REMOVAL | REMOVE_RECV | RING_RECOVER))						      DPRINTK("New ring status: %02X\n", ring_status);					      if (ring_status & LOG_OVERFLOW) {						      if (dev->tbusy)                                                              ti->readlog_pending = 1;						      else                                                              ibmtr_readlog(dev);					      }				      }				      break;				      case XMIT_DATA_REQ:					tr_tx(dev);					break;				      default:					DPRINTK("Unknown command %02X in arb\n",						(int)readb(ti->arb));					break;				} /* ARB command check */				writeb(~ARB_CMD_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);				writeb(ARB_FREE, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);			} /* ARB response */			if (status & SSB_RESP_INT) { /* SSB response */				unsigned char retcode;				switch (readb(ti->ssb)) { /* SSB command check */				      				      case XMIT_DIR_FRAME:				      case XMIT_UI_FRAME:					retcode = readb(ti->ssb+2);					if (retcode && (retcode != 0x22)) /* checks ret_code */						DPRINTK("xmit ret_code: %02X xmit error code: %02X\n",							(int)retcode, (int)readb(ti->ssb+6));					else ti->tr_stats.tx_packets++;					break;				      case XMIT_XID_CMD:					DPRINTK("xmit xid ret_code: %02X\n", (int)readb(ti->ssb+2));				      default:					DPRINTK("Unknown command %02X in ssb\n", (int)readb(ti->ssb));				} /* SSB command check */				writeb(~SSB_RESP_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);				writeb(SSB_FREE, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);			} /* SSB response */		}	 /* SRB, ARB, ASB or SSB response */		dev->interrupt=0;		writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);		break;	      case FIRST_INT:		initial_tok_int(dev);		break;	      default:		DPRINTK("Unexpected interrupt from tr adapter\n");	}	spin_unlock(&(ti->lock));}static void initial_tok_int(struct device *dev){	__u32 encoded_addr;	__u32 hw_encoded_addr;	struct tok_info *ti;	ti=(struct tok_info *) dev->priv;	ti->do_tok_int=NOT_FIRST;#ifndef TR_NEWFORMAT	DPRINTK("Initial tok int received\n");#endif	/* we assign the shared-ram address for ISA devices */	if(!ti->sram) {		writeb(ti->sram_base, ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN);		ti->sram=((__u32)ti->sram_base << 12);	}	ti->init_srb=ti->sram		+ntohs((unsigned short)readw(ti->mmio+ ACA_OFFSET + WRBR_EVEN));	SET_PAGE(ntohs((unsigned short)readw(ti->mmio+ACA_OFFSET + WRBR_EVEN)));	dev->mem_start = ti->sram;	dev->mem_end = ti->sram + (ti->mapped_ram_size<<9) - 1;#if TR_VERBOSE	{		int i;		DPRINTK("init_srb(%p):", ti->init_srb);		for (i=0;i<17;i++) printk("%02X ", (int)readb(ti->init_srb+i));		printk("\n");	}#endif	hw_encoded_addr = readw(ti->init_srb				+ offsetof(struct srb_init_response, encoded_address));#if !TR_NEWFORMAT	DPRINTK("srb_init_response->encoded_address: %04X\n", hw_encoded_addr);	DPRINTK("ntohs(srb_init_response->encoded_address): %04X\n",		ntohs(hw_encoded_addr));#endif	encoded_addr=(ti->sram + ntohs(hw_encoded_addr));	ti->ring_speed = readb(ti->init_srb+offsetof(struct srb_init_response, init_status)) & 0x01 ? 16 : 4;#if !TR_NEWFORMAT	DPRINTK("encoded addr (%04X,%04X,%08X): ", hw_encoded_addr,		ntohs(hw_encoded_addr), encoded_addr);#else	DPRINTK("Initial interrupt : %d Mbps, shared RAM base %08x.\n",		ti->ring_speed, ti->sram);#endif	ti->auto_ringspeedsave=readb(ti->init_srb				     +offsetof(struct srb_init_response, init_status_2)) & 0x4 ? TRUE : FALSE;#if !TR_NEWFORMAT	for(i=0;i<TR_ALEN;i++) {		dev->dev_addr[i]=readb(encoded_addr + i);		printk("%02X%s", dev->dev_addr[i], (i==TR_ALEN-1) ? "" : ":" );	}	printk("\n");#endif	tok_open_adapter((unsigned long)dev);}static int tok_init_card(struct device *dev){	struct tok_info *ti;	short PIOaddr;	unsigned long i;	PIOaddr = dev->base_addr;	ti=(struct tok_info *) dev->priv;	/* Special processing for first interrupt after reset */	ti->do_tok_int=FIRST_INT;	/* Reset adapter */	dev->tbusy=1; /* nothing can be done before reset and open completed */#ifdef ENABLE_PAGING	if(ti->page_mask)		writeb(SRPR_ENABLE_PAGING, ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN);#endif	writeb(~INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN);#if !TR_NEWFORMAT	DPRINTK("resetting card\n");#endif	outb(0, PIOaddr+ADAPTRESET);	for (i=jiffies+TR_RESET_INTERVAL; time_before_eq(jiffies, i);); /* wait 50ms */	outb(0,PIOaddr+ADAPTRESETREL);#if !TR_NEWFORMAT	DPRINTK("card reset\n");#endif	ti->open_status=IN_PROGRESS;	writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);	return 0;}static void open_sap(unsigned char type,struct device *dev){	int i;	struct tok_info *ti=(struct tok_info *) dev->priv;	SET_PAGE(ti->srb);	for (i=0; i<sizeof(struct dlc_open_sap); i++)		writeb(0, ti->srb+i);	writeb(DLC_OPEN_SAP, ti->srb + offsetof(struct dlc_open_sap, command));

⌨️ 快捷键说明

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