📄 ibmtr.c
字号:
#endif /* Disable interrupts till processing is finished */ writeb((~INT_ENABLE), ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN); /* Reset interrupt for ISA boards */ if (ti->adapter_int_enable) outb(0, ti->adapter_int_enable); else /* used for PCMCIA cards */ outb(0, ti->global_int_enable); if (ti->do_tok_int == FIRST_INT){ initial_tok_int(dev);#ifdef ENABLE_PAGING writeb(save_srpr, ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN);#endif spin_unlock(&(ti->lock)); return IRQ_HANDLED; } /* Begin interrupt handler HERE inline to avoid the extra levels of logic and call depth for the original solution. */ status = readb(ti->mmio + ACA_OFFSET + ACA_RW + ISRP_ODD); /*BMSstatus_even = readb (ti->mmio + ACA_OFFSET + ACA_RW + ISRP_EVEN) */ /*BMSdebugprintk("tok_interrupt: ISRP_ODD = 0x%x ISRP_EVEN = 0x%x\n", */ /*BMS status,status_even); */ if (status & ADAP_CHK_INT) { int i; void __iomem *check_reason; __u8 check_reason_page = 0; check_reason = map_address(ti, ntohs(readw(ti->mmio+ ACA_OFFSET+ACA_RW + WWCR_EVEN)), &check_reason_page); SET_PAGE(check_reason_page); DPRINTK("Adapter check interrupt\n"); 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); status = readb(ti->mmio + ACA_OFFSET + ACA_RW + ISRA_EVEN); DPRINTK("ISRA_EVEN == 0x02%x\n",status); ti->open_status = CLOSED; ti->sap_status = CLOSED; ti->open_mode = AUTOMATIC; netif_carrier_off(dev); netif_stop_queue(dev); ti->open_action = RESTART; outb(0, dev->base_addr + ADAPTRESET); ibmtr_reset_timer(&(ti->tr_timer), dev);/*BMS try to reopen*/ spin_unlock(&(ti->lock)); return IRQ_HANDLED; } 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); status= readb(ti->mmio+ ACA_OFFSET + ACA_RW + ISRA_EVEN);/*BMS*/ DPRINTK("ISRA_EVEN == 0x02%x\n",status);/*BMS*/ writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);#ifdef ENABLE_PAGING writeb(save_srpr, ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN);#endif spin_unlock(&(ti->lock)); return IRQ_HANDLED; } if (status & SRB_RESP_INT) { /* SRB response */ SET_PAGE(ti->srb_page);#if TR_VERBOSE DPRINTK("SRB resp: cmd=%02X rsp=%02X\n", readb(ti->srb), readb(ti->srb + RETCODE_OFST));#endif switch (readb(ti->srb)) { /* SRB command check */ case XMIT_DIR_FRAME:{ unsigned char xmit_ret_code; xmit_ret_code = readb(ti->srb + RETCODE_OFST); if (xmit_ret_code == 0xff) break; DPRINTK("error on xmit_dir_frame request: %02X\n", xmit_ret_code); if (ti->current_skb) { dev_kfree_skb_irq(ti->current_skb); ti->current_skb = NULL; } /*dev->tbusy = 0;*/ netif_wake_queue(dev); if (ti->readlog_pending) ibmtr_readlog(dev); break; } case XMIT_UI_FRAME:{ unsigned char xmit_ret_code; xmit_ret_code = readb(ti->srb + RETCODE_OFST); if (xmit_ret_code == 0xff) break; DPRINTK("error on xmit_ui_frame request: %02X\n", xmit_ret_code); if (ti->current_skb) { dev_kfree_skb_irq(ti->current_skb); ti->current_skb = NULL; } netif_wake_queue(dev); if (ti->readlog_pending) ibmtr_readlog(dev); break; } case DIR_OPEN_ADAPTER: dir_open_adapter(dev); break; case DLC_OPEN_SAP: if (readb(ti->srb + RETCODE_OFST)) { DPRINTK("open_sap failed: ret_code = %02X, " "retrying\n", (int) readb(ti->srb + RETCODE_OFST)); ti->open_action = REOPEN; ibmtr_reset_timer(&(ti->tr_timer), dev); break; } ti->exsap_station_id = readw(ti->srb + STATION_ID_OFST); ti->sap_status = OPEN;/* TR adapter is now available */ if (ti->open_mode==MANUAL){ wake_up(&ti->wait_for_reset); break; } netif_wake_queue(dev); netif_carrier_on(dev); 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 + RETCODE_OFST)) DPRINTK("error on %02X: %02X\n", (int) readb(ti->srb + COMMAND_OFST), (int) readb(ti->srb + RETCODE_OFST)); break; case DIR_READ_LOG: if (readb(ti->srb + RETCODE_OFST)){ DPRINTK("error on dir_read_log: %02X\n", (int) readb(ti->srb + RETCODE_OFST)); netif_wake_queue(dev); break; }#if IBMTR_DEBUG_MESSAGES#define LINE_ERRORS_OFST 0#define INTERNAL_ERRORS_OFST 1#define BURST_ERRORS_OFST 2#define AC_ERRORS_OFST 3#define ABORT_DELIMITERS_OFST 4#define LOST_FRAMES_OFST 6#define RECV_CONGEST_COUNT_OFST 7#define FRAME_COPIED_ERRORS_OFST 8#define FREQUENCY_ERRORS_OFST 9#define TOKEN_ERRORS_OFST 10 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\nFrequency errors %02X, " "Token errors %02X\n", (int) readb(ti->srb + LINE_ERRORS_OFST), (int) readb(ti->srb + INTERNAL_ERRORS_OFST), (int) readb(ti->srb + BURST_ERRORS_OFST), (int) readb(ti->srb + AC_ERRORS_OFST), (int) readb(ti->srb + ABORT_DELIMITERS_OFST), (int) readb(ti->srb + LOST_FRAMES_OFST), (int) readb(ti->srb + RECV_CONGEST_COUNT_OFST), (int) readb(ti->srb + FRAME_COPIED_ERRORS_OFST), (int) readb(ti->srb + FREQUENCY_ERRORS_OFST), (int) readb(ti->srb + TOKEN_ERRORS_OFST));#endif netif_wake_queue(dev); break; default: DPRINTK("Unknown command %02X encountered\n", (int) readb(ti->srb)); } /* end switch SRB command check */ writeb(~SRB_RESP_INT, ti->mmio+ ACA_OFFSET+ACA_RESET+ ISRP_ODD); } /* if SRB response */ if (status & ASB_FREE_INT) { /* ASB response */ SET_PAGE(ti->asb_page);#if TR_VERBOSE DPRINTK("ASB resp: cmd=%02X\n", readb(ti->asb));#endif 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)); } /* switch 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); } /* if ASB response */#define STATUS_OFST 6#define NETW_STATUS_OFST 6 if (status & ARB_CMD_INT) { /* ARB response */ SET_PAGE(ti->arb_page);#if TR_VERBOSE DPRINTK("ARB resp: cmd=%02X\n", readb(ti->arb));#endif switch (readb(ti->arb)) { /* ARB command check */ case DLC_STATUS: DPRINTK("DLC_STATUS new status: %02X on station %02X\n", ntohs(readw(ti->arb + STATUS_OFST)), ntohs(readw(ti->arb+ STATION_ID_OFST))); break; case REC_DATA: tr_rx(dev); break; case RING_STAT_CHANGE:{ unsigned short ring_status; ring_status= ntohs(readw(ti->arb + NETW_STATUS_OFST)); if (ibmtr_debug_trace & TRC_INIT) DPRINTK("Ring Status Change...(0x%x)\n", ring_status); if(ring_status& (REMOVE_RECV|AUTO_REMOVAL|LOBE_FAULT)){ netif_stop_queue(dev); netif_carrier_off(dev); DPRINTK("Remove received, or Auto-removal error" ", or Lobe fault\n"); DPRINTK("We'll try to reopen the closed adapter" " after a %d second delay.\n", TR_RETRY_INTERVAL/HZ); /*I was confused: I saw the TR reopening but */ /*forgot:with an RJ45 in an RJ45/ICS adapter */ /*but adapter not in the ring, the TR will */ /* open, and then soon close and come here. */ ti->open_mode = AUTOMATIC; ti->open_status = CLOSED; /*12/2000 BMS*/ ti->open_action = REOPEN; ibmtr_reset_timer(&(ti->tr_timer), dev); } else if (ring_status & LOG_OVERFLOW) { if(netif_queue_stopped(dev)) 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; } /* switch 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); } /* if ARB response */ if (status & SSB_RESP_INT) { /* SSB response */ unsigned char retcode; SET_PAGE(ti->ssb_page);#if TR_VERBOSE DPRINTK("SSB resp: cmd=%02X rsp=%02X\n", readb(ti->ssb), readb(ti->ssb + 2));#endif 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); } /* if SSB response */#ifdef ENABLE_PAGING writeb(save_srpr, ti->mmio + ACA_OFFSET + ACA_RW + SRPR_EVEN);#endif writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN); spin_unlock(&(ti->lock)); return IRQ_HANDLED;} /*tok_interrupt *//*****************************************************************************/#define INIT_STATUS_OFST 1#define INIT_STATUS_2_OFST 2#define ENCODED_ADDRESS_OFST 8static void initial_tok_int(struct net_device *dev){ __u32 encoded_addr, hw_encoded_addr; struct tok_info *ti; unsigned char init_status; /*BMS 12/2000*/ ti = (struct tok_info *) dev->priv; ti->do_tok_int = NOT_FIRST; /* we assign the shared-ram address for ISA devices */ writeb(ti->sram_base, ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN);#ifndef PCMCIA ti->sram_virt = ioremap(((__u32)ti->sram_base << 12), ti->avail_shared_ram);#endif ti->init_srb = map_address(ti, ntohs(readw(ti->mmio + ACA_OFFSET + WRBR_EVEN)), &ti->init_srb_page); if (ti->page_mask && ti->avail_shared_ram == 127) { void __iomem *last_512; __u8 last_512_page=0; int i; last_512 = map_address(ti, 0xfe00, &last_512_page); /* initialize high section of ram (if necessary) */ SET_PAGE(last_512_page); for (i = 0; i < 512; i++) writeb(0, last_512 + i); } SET_PAGE(ti->init_srb_page);#if TR_VERBOSE { int i; DPRINTK("ti->init_srb_page=0x%x\n", ti->init_srb_page); DPRINTK("init_srb(%p):", ti->init_srb ); for (i = 0; i < 20; i++) printk("%02X ", (int) readb(ti->init_srb + i)); printk("\n"); }#endif hw_encoded_addr = readw(ti->init_srb + ENCODED_ADDRESS_OFST); encoded_addr = ntohs(hw_encoded_addr); init_status= /*BMS 12/2000 check for shallow mode possibility (Turbo)*/ readb(ti->init_srb+offsetof(struct srb_init_response,init_status)); /*printk("Initial interrupt: init_status= 0x%02x\n",init_status);*/ ti->ring_speed = init_status & 0x01 ? 16 : 4; DPRINTK("Initial interrupt : %d Mbps, shared RAM base %08x.\n", ti->ring_speed, (unsigned int)dev->mem_start); ti->auto_speedsave=readb(ti->init_srb+INIT_STATUS_2_OFST)&4?TRUE:FALSE; if (ti->open_mode == MANUAL) wake_up(&ti->wait_for_reset); else tok_open_adapter((unsigned long)dev); } /*initial_tok_int() *//*****************************************************************************/#define CMD_CORRELATE_OFST 1#define DHB_ADDRESS_OFST 6#define FRAME_LENGTH_OFST 6#define HEADER_LENGTH_OFST 8#define RSAP_VALUE_OFST 9static void tr_tx(struct net_device *dev){ struct tok_info *ti = (struct tok_info *) dev->priv; struct trh_hdr *trhdr = (struct trh_hdr *) ti->current_skb->data; unsigned int hdr_len; __u32 dhb=0,dhb_base; void __iomem *dhbuf = NULL; unsigned char xmit_command; int i,dhb_len=0x4000,src_len,src_offset; struct trllc *llc; struct srb_xmit xsrb; __u8 dhb_page = 0; __u8 llc_ssap; SET_PAGE(ti->asb_page); if (readb(ti->asb+RETCODE_OFST) != 0xFF) DPRINTK("ASB not free !!!\n"); /* in providing the transmit interrupts, is telling us it is ready for data and providing a shared memory address for us to stuff with data. Here we compute the effective address where we will place data. */ SET_PAGE(ti->arb_page);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -