/* * Assume that the following function, sampleQDIntVector(), is registered * when BSP calls intConnect for QD Interrupt. * This sample will show how to deal with QuarterDeck Interrupt. */ GT_STATUS sampleQDIntVector(GT_QD_DEV *dev) { GT_U16 intCause, phyIntCause; GT_U16 portVec; GT_LPORT port; GT_VTU_INT_STATUS vtuInt; GT_ATU_INT_STATUS atuInt; /* * Disable QuarterDeck Interrupt in System Level. * ToDo... */ /* * Check if QD generated the interrupt. */ if(eventGetIntStatus(dev,&intCause) != GT_OK) { /* QD didn't generate the interrupt. */ return GT_FAIL; } /* * QD generated interrupt with the reason in intCause. */ if(intCause & GT_STATS_DONE) { /* * Statistics Done Interrupt * ToDo... */ } if(intCause & GT_VTU_DONE) { /* * VTU Done Interrupt * ToDo... */ } if(intCause & GT_VTU_PROB) { /* * Vlan Table Problem/Violation. * Need to read the cause. */ do { if(gvtuGetIntStatus(dev,&vtuInt) != GT_OK) { /* failed to retrieve VTU Interrupt cause */ break; } if(vtuInt.vtuIntCause & GT_VTU_FULL_VIOLATION) { /* * Vlan Table is Full * ToDo... */ } if(vtuInt.vtuIntCause & GT_MEMBER_VIOLATION) { /* * Member Violation * ToDo... */ } if(vtuInt.vtuIntCause & GT_MISS_VIOLATION) { /* * Miss Violation * ToDo... */ } } while(vtuInt.vtuIntCause != 0); } if(intCause & GT_ATU_PROB) { /* * ATU cannot load or learn a new mapping due to all the available * locations for an address being locked. * ToDo... */ do { if(gatuGetIntStatus(dev,&atuInt) != GT_OK) { /* failed to retrieve VTU Interrupt cause */ break; } if(atuInt.atuIntCause & GT_FULL_VIOLATION) { /* * Table is Full * ToDo... */ } if(atuInt.atuIntCause & GT_MEMBER_VIOLATION) { /* * Member Violation * ToDo... */ } if(atuInt.atuIntCause & GT_MISS_VIOLATION) { /* * Miss Violation * ToDo... */ } } while(atuInt.atuIntCause != 0); } if(intCause & GT_ATU_DONE) { /* * There is a transitions from a one to a zero on ATUBusy bit * (Refer to ATU Operation Register.) * ToDo... */ } if(intCause & GT_PHY_INTERRUPT) { /* * At least one of the Phy generated interrupt. * We need to read Phy Interrupt Summary and go through each phy * based on the summary. */ if(gprtGetPhyIntPortSummary(dev,&portVec) != GT_OK) { return GT_FAIL; } port = 0; while(portVec) { if(portVec & 0x01) { /* * Call gprtGetPhyIntStatus to get intCause */ if(gprtGetPhyIntStatus(dev,port,&phyIntCause) != GT_OK) { /* * Something wrong with the system. Need to do the * necessary work. * ToDo... */ } if(phyIntCause & GT_SPEED_CHANGED) { /* * Speed has been changed. * ToDo... */ } if(phyIntCause & GT_DUPLEX_CHANGED) { /* * Duplex mode has been changed. * ToDo... */ } if(phyIntCause & GT_PAGE_RECEIVED) { /* * Page received. * ToDo... */ } if(phyIntCause & GT_AUTO_NEG_COMPLETED) { /* * AutoNegotiation completed. * ToDo... */ } if(phyIntCause & GT_LINK_STATUS_CHANGED) { /* * Link Status changed. * ToDo... */ } if(phyIntCause & GT_SYMBOL_ERROR) { /* * Symbol error * ToDo... */ } if(phyIntCause & GT_FALSE_CARRIER) { /* * False Carrier. * ToDo... */ } if(phyIntCause & GT_FIFO_FLOW) { /* * Fifo Overflow/underflow error * ToDo... */ } if(phyIntCause & GT_CROSSOVER_CHANGED) { /* * MDI/MDIX crossover changed. * ToDo... */ } if(phyIntCause & GT_POLARITY_CHANGED) { /* * Polarity changed. * ToDo... */ } if(phyIntCause & GT_JABBER) { /* * Jabber * ToDo... */ } } portVec >>= 1; port++; } } if(intCause & GT_EE_INTERRUPT) { /* * EEPROM is done loading registers. * ToDo... */ } /* * Now, all the QuarterDeck related interrupt have been cleared, * so it's OK to enable QuarterDeck Interrupt in System Level. * ToDo... */ return GT_OK; }
GT_STATUS samplePTPIntHandler(GT_QD_DEV *dev) { GT_U32 int_ports, i, int_status; GT_STATUS status; GT_PTP_TS_STATUS ptpStatus; /* disable AVB Interrupt */ eventSetActive(dev, 0); /* read interrupt cause */ if((status=eventGetIntStatus(dev,(GT_U16*)&int_status))!=GT_OK) { return GT_FAIL; } if ((int_status & GT_AVB_INT) == 0) { MSG_PRINT(("eventGetIntStatus return No AVB Interrupt\n")); /* it's not PTP interrupt */ goto ret_int; } /* read AVB Int status */ if((status = gptpGetPTPInt(dev, &int_ports)) != GT_OK) { MSG_PRINT(("gptpGetPTPInt return failed\n")); goto ret_int; } /* for each port, get the timestamp information if necessary */ i = 0; while(int_ports) { if(!(int_ports & 0x1)) { i++; int_ports >>= 1; continue; } /* check Arrival0 Time Stamp */ if((status = gptpGetTimeStamped(dev, i, PTP_ARR0_TIME, &ptpStatus)) != GT_OK) { MSG_PRINT(("gptpGetTimeStamped return failed\n")); goto ret_int; } if (ptpStatus.isValid == GT_TRUE) { switch(ptpStatus.status) { case PTP_INT_NORMAL: /* To Do: No error condition occurred. So store the time stamp and seqId */ break; case PTP_INT_OVERWRITE: /* To Do: PTP Logic received several PTP frames and only the last one is valid */ break; case PTP_INT_DROP: /* To Do: PTP Logic received several PTP frames and only the first one is valid */ break; default: MSG_PRINT(("unknown ptp status %i\n", ptpStatus.status)); status = GT_FAIL; goto ret_int; } if((status = gptpResetTimeStamp(dev, i, PTP_ARR0_TIME)) != GT_OK) { MSG_PRINT(("gptpResetTimeStamp return failed\n")); goto ret_int; } } /* check Arrival1 Time Stamp */ if((status = gptpGetTimeStamped(dev, i, PTP_ARR1_TIME, &ptpStatus)) != GT_OK) { MSG_PRINT(("gptpGetTimeStamped return failed\n")); goto ret_int; } if (ptpStatus.isValid == GT_TRUE) { switch(ptpStatus.status) { case PTP_INT_NORMAL: /* To Do: No error condition occurred. So store the time stamp and seqId */ break; case PTP_INT_OVERWRITE: /* To Do: PTP Logic received several PTP frames and only the last one is valid */ break; case PTP_INT_DROP: /* To Do: PTP Logic received several PTP frames and only the first one is valid */ break; default: MSG_PRINT(("unknown ptp status %i\n", ptpStatus.status)); status = GT_FAIL; goto ret_int; } if((status = gptpResetTimeStamp(dev, i, PTP_ARR1_TIME)) != GT_OK) { MSG_PRINT(("gptpResetTimeStamp return failed\n")); goto ret_int; } } /* check Departure Time Stamp */ if((status = gptpGetTimeStamped(dev, i, PTP_DEP_TIME, &ptpStatus)) != GT_OK) { MSG_PRINT(("gptpGetTimeStamped return failed\n")); goto ret_int; } if (ptpStatus.isValid == GT_TRUE) { switch(ptpStatus.status) { case PTP_INT_NORMAL: /* To Do: No error condition occurred. So store the time stamp and seqId */ break; case PTP_INT_OVERWRITE: /* To Do: PTP Logic received several PTP frames and only the last one is valid */ break; case PTP_INT_DROP: /* To Do: PTP Logic received several PTP frames and only the first one is valid */ break; default: MSG_PRINT(("unknown ptp status %i\n", ptpStatus.status)); status = GT_FAIL; goto ret_int; } if((status = gptpResetTimeStamp(dev, i, PTP_DEP_TIME)) != GT_OK) { MSG_PRINT(("gptpResetTimeStamp return failed\n")); goto ret_int; } } int_ports >>= 1; }
static irqreturn_t mv_gtw_link_interrupt_handler(int irq , void *dev_id) { unsigned short switch_cause = 0, phy_cause, phys_port = 0, p; OUT GT_DEV_INT_STATUS devIntStatus; if (switch_irq != -1 ) { if ((qd_dev->deviceId == GT_88E6161) || (qd_dev->deviceId == GT_88E6165) || (qd_dev->deviceId == GT_88E6171)) { /* required to clear the interrupt, and updates phys_port */ if (geventGetDevIntStatus(qd_dev, &devIntStatus) != GT_OK) { printk("geventGetDevIntStatus failed, ignoring interrupt\n"); return IRQ_HANDLED; } if (devIntStatus.devIntCause != GT_DEV_INT_PHY) { printk("devIntCause != GT_DEV_INT_PHY, igonring interrupt\n"); return IRQ_HANDLED; } phys_port = devIntStatus.phyInt & 0xFF; if (phys_port) switch_cause = GT_PHY_INTERRUPT; } else { if(eventGetIntStatus(qd_dev, &switch_cause) != GT_OK) switch_cause = 0; } } else { switch_cause = GT_PHY_INTERRUPT; } if(switch_cause & GT_PHY_INTERRUPT) { /* If we're using a 6161/6165 Switch and using the Switch interrupt, we already have phys_port updated above */ /* If we're using any other Switch, or if we're using polling, we need to update phys_port now */ if ((qd_dev->deviceId == GT_88E6161) || (qd_dev->deviceId == GT_88E6165) || (qd_dev->deviceId == GT_88E6171)) { if (switch_irq == -1) { geventGetDevIntStatus(qd_dev, &devIntStatus); phys_port = devIntStatus.phyInt & 0xFF; /* TODO: check if next line is needed */ phys_port |= 0x18; /* we cannot get indication for these ports in this method, so check them */ } } else { /* not 6161 or 6165 */ gprtGetPhyIntPortSummary(qd_dev,&phys_port); } for(p=0; p<qd_dev->numOfPorts; p++) { if (MV_BIT_CHECK(phys_port, p)) { if(gprtGetPhyIntStatus(qd_dev,p,&phy_cause) == GT_OK) { if(phy_cause & GT_LINK_STATUS_CHANGED) { char *link=NULL, *duplex=NULL, *speed=NULL; GT_BOOL flag; GT_PORT_SPEED_MODE speed_mode; if(gprtGetLinkState(qd_dev,p,&flag) != GT_OK) { printk("gprtGetLinkState failed (port %d)\n",p); link = "ERR"; } else link = (flag)?"up":"down"; if(flag) { if(gprtGetDuplex(qd_dev,p,&flag) != GT_OK) { printk("gprtGetDuplex failed (port %d)\n",p); duplex = "ERR"; } else duplex = (flag)?"Full":"Half"; if(gprtGetSpeedMode(qd_dev,p,&speed_mode) != GT_OK) { printk("gprtGetSpeedMode failed (port %d)\n",p); speed = "ERR"; } else { if (speed_mode == PORT_SPEED_1000_MBPS) speed = "1000Mbps"; else if (speed_mode == PORT_SPEED_100_MBPS) speed = "100Mbps"; else speed = "10Mbps"; } mv_gtw_update_link_status(p, 1); printk("Port %d: Link-%s, %s-duplex, Speed-%s.\n", mv_gtw_port2lport(p),link,duplex,speed); } else { mv_gtw_update_link_status(p, 0); printk("Port %d: Link-down\n",mv_gtw_port2lport(p)); } } } } } } if (switch_irq == -1 ) { switch_link_timer.expires = jiffies + (HZ); /* 1 second */ add_timer(&switch_link_timer); } return IRQ_HANDLED; }