Print this page
4778 iprb shouldn't abuse ddi_get_time(9f)
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Garrett D'Amore <garrett@damore.org>


 281         }
 282 
 283         if (ddi_regs_map_setup(dip, 1, &ip->regs, 0, 0, &acc_attr,
 284             &ip->regsh) != DDI_SUCCESS) {
 285                 iprb_error(ip, "unable to map device registers");
 286                 iprb_destroy(ip);
 287                 return (DDI_FAILURE);
 288         }
 289 
 290         /* Reset, but first go into idle state */
 291         PUT32(ip, CSR_PORT, PORT_SEL_RESET);
 292         drv_usecwait(10);
 293         PUT32(ip, CSR_PORT, PORT_SW_RESET);
 294         drv_usecwait(10);
 295         PUT8(ip, CSR_INTCTL, INTCTL_MASK);
 296         (void) GET8(ip, CSR_INTCTL);
 297 
 298         /*
 299          * Precalculate watchdog times.
 300          */
 301         ip->tx_timeout = drv_usectohz(TX_WATCHDOG * 1000000);
 302         ip->rx_timeout = drv_usectohz(RX_WATCHDOG * 1000000);
 303 
 304         iprb_identify(ip);
 305 
 306         /* Obtain our factory MAC address */
 307         w = iprb_eeprom_read(ip, 0);
 308         ip->factaddr[0] = w & 0xff;
 309         ip->factaddr[1] = w >> 8;
 310         w = iprb_eeprom_read(ip, 1);
 311         ip->factaddr[2] = w & 0xff;
 312         ip->factaddr[3] = w >> 8;
 313         w = iprb_eeprom_read(ip, 2);
 314         ip->factaddr[4] = w & 0xff;
 315         ip->factaddr[5] = w >> 8;
 316         bcopy(ip->factaddr, ip->curraddr, 6);
 317 
 318         if (ip->resumebug) {
 319                 /*
 320                  * Generally, most devices we will ever see will
 321                  * already have fixed firmware.  Since I can't verify
 322                  * the validity of the fix (no suitably downrev


 686         return (DDI_FAILURE);
 687 }
 688 
 689 void
 690 iprb_cmd_reclaim(iprb_t *ip)
 691 {
 692         while (ip->cmd_count) {
 693                 iprb_dma_t *cb = &ip->cmds[ip->cmd_tail];
 694 
 695                 SYNCCB(cb, CB_STS_OFFSET, 2, DDI_DMA_SYNC_FORKERNEL);
 696                 if ((GETCB16(cb, CB_STS_OFFSET) & CB_STS_C) == 0) {
 697                         break;
 698                 }
 699 
 700                 ip->cmd_tail++;
 701                 ip->cmd_tail %= NUM_TX;
 702                 ip->cmd_count--;
 703                 if (ip->cmd_count == 0) {
 704                         ip->tx_wdog = 0;
 705                 } else {
 706                         ip->tx_wdog = ddi_get_time();
 707                 }
 708         }
 709 }
 710 
 711 int
 712 iprb_cmd_drain(iprb_t *ip)
 713 {
 714         for (int i = 1000000; i; i -= 10) {
 715                 iprb_cmd_reclaim(ip);
 716                 if (ip->cmd_count == 0)
 717                         return (DDI_SUCCESS);
 718                 drv_usecwait(10);
 719         }
 720         iprb_error(ip, "time out waiting for commands to drain");
 721         return (DDI_FAILURE);
 722 }
 723 
 724 int
 725 iprb_cmd_submit(iprb_t *ip, uint16_t cmd)
 726 {


 758                 if (iprb_cmd_ready(ip) != DDI_SUCCESS)
 759                         return (DDI_FAILURE);
 760                 PUT8(ip, CSR_CMD, CUC_NOP);
 761                 (void) GET8(ip, CSR_CMD);
 762                 drv_usecwait(1);
 763         }
 764 
 765         /* wait for the SCB to be ready to accept a new command */
 766         if (iprb_cmd_ready(ip) != DDI_SUCCESS)
 767                 return (DDI_FAILURE);
 768 
 769         /*
 770          * Finally we can resume the CU.  Note that if this the first
 771          * command in the sequence (i.e. if the CU is IDLE), or if the
 772          * CU is already busy working, then this CU resume command
 773          * will not have any effect.
 774          */
 775         PUT8(ip, CSR_CMD, CUC_RESUME);
 776         (void) GET8(ip, CSR_CMD);       /* flush CSR */
 777 
 778         ip->tx_wdog = ddi_get_time();
 779         ip->cmd_last = ip->cmd_head;
 780         ip->cmd_head++;
 781         ip->cmd_head %= NUM_TX;
 782         ip->cmd_count++;
 783 
 784         return (DDI_SUCCESS);
 785 }
 786 
 787 iprb_dma_t *
 788 iprb_cmd_next(iprb_t *ip)
 789 {
 790         if (ip->cmd_count == NUM_TX) {
 791                 return (NULL);
 792         }
 793         ASSERT(ip->cmd_count < NUM_TX);
 794         return (&ip->cmds[ip->cmd_head]);
 795 }
 796 
 797 int
 798 iprb_set_unicast(iprb_t *ip)


 993         /* Set up RFDs */
 994         iprb_rx_init(ip);
 995 
 996         PUT32(ip, CSR_GEN_PTR, ip->rxb[0].paddr);
 997         /* wait for the SCB */
 998         (void) iprb_cmd_ready(ip);
 999         PUT8(ip, CSR_CMD, RUC_START);
1000         (void) GET8(ip, CSR_CMD);       /* flush CSR */
1001 
1002         /* Enable device interrupts */
1003         PUT8(ip, CSR_INTCTL, 0);
1004         (void) GET8(ip, CSR_INTCTL);
1005 
1006         return (DDI_SUCCESS);
1007 }
1008 
1009 void
1010 iprb_update_stats(iprb_t *ip)
1011 {
1012         iprb_dma_t      *sp = &ip->stats;
1013         time_t          tstamp;
1014         int             i;
1015 
1016         ASSERT(mutex_owned(&ip->culock));
1017 
1018         /* Collect the hardware stats, but don't keep redoing it */
1019         if ((tstamp = ddi_get_time()) == ip->stats_time) {

1020                 return;
1021         }
1022 
1023         PUTSTAT(sp, STATS_DONE_OFFSET, 0);
1024         SYNCSTATS(sp, 0, 0, DDI_DMA_SYNC_FORDEV);
1025 
1026         if (iprb_cmd_ready(ip) != DDI_SUCCESS)
1027                 return;
1028         PUT32(ip, CSR_GEN_PTR, sp->paddr);
1029         PUT8(ip, CSR_CMD, CUC_STATSBASE);
1030         (void) GET8(ip, CSR_CMD);
1031 
1032         if (iprb_cmd_ready(ip) != DDI_SUCCESS)
1033                 return;
1034         PUT8(ip, CSR_CMD, CUC_STATS_RST);
1035         (void) GET8(ip, CSR_CMD);       /* flush wb */
1036 
1037         for (i = 10000; i; i -= 10) {
1038                 SYNCSTATS(sp, 0, 0, DDI_DMA_SYNC_FORKERNEL);
1039                 if (GETSTAT(sp, STATS_DONE_OFFSET) == STATS_RST_DONE) {
1040                         /* yay stats are updated */
1041                         break;


1157 iprb_rx(iprb_t *ip)
1158 {
1159         iprb_dma_t      *rfd;
1160         uint16_t        cnt;
1161         uint16_t        sts;
1162         int             i;
1163         mblk_t          *mplist;
1164         mblk_t          **mpp;
1165         mblk_t          *mp;
1166 
1167         mplist = NULL;
1168         mpp = &mplist;
1169 
1170         for (i = 0; i < NUM_RX; i++) {
1171                 rfd = &ip->rxb[ip->rx_index];
1172                 SYNCRFD(rfd, RFD_STS_OFFSET, 2, DDI_DMA_SYNC_FORKERNEL);
1173                 if ((GETRFD16(rfd, RFD_STS_OFFSET) & RFD_STS_C) == 0) {
1174                         break;
1175                 }
1176 
1177                 ip->rx_wdog = ddi_get_time();
1178 
1179                 SYNCRFD(rfd, 0, 0, DDI_DMA_SYNC_FORKERNEL);
1180                 cnt = GETRFD16(rfd, RFD_CNT_OFFSET);
1181                 cnt &= ~(RFD_CNT_EOF | RFD_CNT_F);
1182                 sts = GETRFD16(rfd, RFD_STS_OFFSET);
1183 
1184                 if (cnt > (ETHERMAX + VLAN_TAGSZ)) {
1185                         ip->toolong++;
1186                         iprb_rx_add(ip);
1187                         continue;
1188                 }
1189                 if (((sts & RFD_STS_OK) == 0) && (sts & RFD_STS_ERRS)) {
1190                         iprb_rx_add(ip);
1191                         continue;
1192                 }
1193                 if ((mp = allocb(cnt, BPRI_MED)) == NULL) {
1194                         ip->norcvbuf++;
1195                         iprb_rx_add(ip);
1196                         continue;
1197                 }


1646 
1647 void
1648 iprb_periodic(void *arg)
1649 {
1650         iprb_t *ip = arg;
1651         boolean_t reset = B_FALSE;
1652 
1653         mutex_enter(&ip->rulock);
1654         if (ip->suspended || !ip->running) {
1655                 mutex_exit(&ip->rulock);
1656                 return;
1657         }
1658 
1659         /*
1660          * If we haven't received a packet in a while, and if the link
1661          * is up, then it might be a hung chip.  This problem
1662          * reportedly only occurs at 10 Mbps.
1663          */
1664         if (ip->rxhangbug &&
1665             ((ip->miih == NULL) || (mii_get_speed(ip->miih) == 10000000)) &&
1666             ((ddi_get_time() - ip->rx_wdog) > ip->rx_timeout)) {
1667                 cmn_err(CE_CONT, "?Possible RU hang, resetting.\n");
1668                 reset = B_TRUE;
1669         }
1670 
1671         /* update the statistics */
1672         mutex_enter(&ip->culock);
1673 
1674         if (ip->tx_wdog && ((ddi_get_time() - ip->tx_wdog) > ip->tx_timeout)) {
1675                 /* transmit/CU hang? */
1676                 cmn_err(CE_CONT, "?CU stalled, resetting.\n");
1677                 reset = B_TRUE;
1678         }
1679 
1680         if (reset) {
1681                 /* We want to reconfigure */
1682                 iprb_stop(ip);
1683                 if (iprb_start(ip) != DDI_SUCCESS) {
1684                         iprb_error(ip, "unable to restart chip");
1685                 }
1686         }
1687 
1688         iprb_update_stats(ip);
1689 
1690         mutex_exit(&ip->culock);
1691         mutex_exit(&ip->rulock);
1692 }
1693 
1694 int




 281         }
 282 
 283         if (ddi_regs_map_setup(dip, 1, &ip->regs, 0, 0, &acc_attr,
 284             &ip->regsh) != DDI_SUCCESS) {
 285                 iprb_error(ip, "unable to map device registers");
 286                 iprb_destroy(ip);
 287                 return (DDI_FAILURE);
 288         }
 289 
 290         /* Reset, but first go into idle state */
 291         PUT32(ip, CSR_PORT, PORT_SEL_RESET);
 292         drv_usecwait(10);
 293         PUT32(ip, CSR_PORT, PORT_SW_RESET);
 294         drv_usecwait(10);
 295         PUT8(ip, CSR_INTCTL, INTCTL_MASK);
 296         (void) GET8(ip, CSR_INTCTL);
 297 
 298         /*
 299          * Precalculate watchdog times.
 300          */
 301         ip->tx_timeout = TX_WATCHDOG;
 302         ip->rx_timeout = RX_WATCHDOG;
 303 
 304         iprb_identify(ip);
 305 
 306         /* Obtain our factory MAC address */
 307         w = iprb_eeprom_read(ip, 0);
 308         ip->factaddr[0] = w & 0xff;
 309         ip->factaddr[1] = w >> 8;
 310         w = iprb_eeprom_read(ip, 1);
 311         ip->factaddr[2] = w & 0xff;
 312         ip->factaddr[3] = w >> 8;
 313         w = iprb_eeprom_read(ip, 2);
 314         ip->factaddr[4] = w & 0xff;
 315         ip->factaddr[5] = w >> 8;
 316         bcopy(ip->factaddr, ip->curraddr, 6);
 317 
 318         if (ip->resumebug) {
 319                 /*
 320                  * Generally, most devices we will ever see will
 321                  * already have fixed firmware.  Since I can't verify
 322                  * the validity of the fix (no suitably downrev


 686         return (DDI_FAILURE);
 687 }
 688 
 689 void
 690 iprb_cmd_reclaim(iprb_t *ip)
 691 {
 692         while (ip->cmd_count) {
 693                 iprb_dma_t *cb = &ip->cmds[ip->cmd_tail];
 694 
 695                 SYNCCB(cb, CB_STS_OFFSET, 2, DDI_DMA_SYNC_FORKERNEL);
 696                 if ((GETCB16(cb, CB_STS_OFFSET) & CB_STS_C) == 0) {
 697                         break;
 698                 }
 699 
 700                 ip->cmd_tail++;
 701                 ip->cmd_tail %= NUM_TX;
 702                 ip->cmd_count--;
 703                 if (ip->cmd_count == 0) {
 704                         ip->tx_wdog = 0;
 705                 } else {
 706                         ip->tx_wdog = gethrtime();
 707                 }
 708         }
 709 }
 710 
 711 int
 712 iprb_cmd_drain(iprb_t *ip)
 713 {
 714         for (int i = 1000000; i; i -= 10) {
 715                 iprb_cmd_reclaim(ip);
 716                 if (ip->cmd_count == 0)
 717                         return (DDI_SUCCESS);
 718                 drv_usecwait(10);
 719         }
 720         iprb_error(ip, "time out waiting for commands to drain");
 721         return (DDI_FAILURE);
 722 }
 723 
 724 int
 725 iprb_cmd_submit(iprb_t *ip, uint16_t cmd)
 726 {


 758                 if (iprb_cmd_ready(ip) != DDI_SUCCESS)
 759                         return (DDI_FAILURE);
 760                 PUT8(ip, CSR_CMD, CUC_NOP);
 761                 (void) GET8(ip, CSR_CMD);
 762                 drv_usecwait(1);
 763         }
 764 
 765         /* wait for the SCB to be ready to accept a new command */
 766         if (iprb_cmd_ready(ip) != DDI_SUCCESS)
 767                 return (DDI_FAILURE);
 768 
 769         /*
 770          * Finally we can resume the CU.  Note that if this the first
 771          * command in the sequence (i.e. if the CU is IDLE), or if the
 772          * CU is already busy working, then this CU resume command
 773          * will not have any effect.
 774          */
 775         PUT8(ip, CSR_CMD, CUC_RESUME);
 776         (void) GET8(ip, CSR_CMD);       /* flush CSR */
 777 
 778         ip->tx_wdog = gethrtime();
 779         ip->cmd_last = ip->cmd_head;
 780         ip->cmd_head++;
 781         ip->cmd_head %= NUM_TX;
 782         ip->cmd_count++;
 783 
 784         return (DDI_SUCCESS);
 785 }
 786 
 787 iprb_dma_t *
 788 iprb_cmd_next(iprb_t *ip)
 789 {
 790         if (ip->cmd_count == NUM_TX) {
 791                 return (NULL);
 792         }
 793         ASSERT(ip->cmd_count < NUM_TX);
 794         return (&ip->cmds[ip->cmd_head]);
 795 }
 796 
 797 int
 798 iprb_set_unicast(iprb_t *ip)


 993         /* Set up RFDs */
 994         iprb_rx_init(ip);
 995 
 996         PUT32(ip, CSR_GEN_PTR, ip->rxb[0].paddr);
 997         /* wait for the SCB */
 998         (void) iprb_cmd_ready(ip);
 999         PUT8(ip, CSR_CMD, RUC_START);
1000         (void) GET8(ip, CSR_CMD);       /* flush CSR */
1001 
1002         /* Enable device interrupts */
1003         PUT8(ip, CSR_INTCTL, 0);
1004         (void) GET8(ip, CSR_INTCTL);
1005 
1006         return (DDI_SUCCESS);
1007 }
1008 
1009 void
1010 iprb_update_stats(iprb_t *ip)
1011 {
1012         iprb_dma_t      *sp = &ip->stats;
1013         hrtime_t        tstamp;
1014         int             i;
1015 
1016         ASSERT(mutex_owned(&ip->culock));
1017 
1018         /* Collect the hardware stats, but don't keep redoing it */
1019         tstamp = gethrtime();
1020         if (tstamp / NANOSEC == ip->stats_time / NANOSEC)
1021                 return;

1022 
1023         PUTSTAT(sp, STATS_DONE_OFFSET, 0);
1024         SYNCSTATS(sp, 0, 0, DDI_DMA_SYNC_FORDEV);
1025 
1026         if (iprb_cmd_ready(ip) != DDI_SUCCESS)
1027                 return;
1028         PUT32(ip, CSR_GEN_PTR, sp->paddr);
1029         PUT8(ip, CSR_CMD, CUC_STATSBASE);
1030         (void) GET8(ip, CSR_CMD);
1031 
1032         if (iprb_cmd_ready(ip) != DDI_SUCCESS)
1033                 return;
1034         PUT8(ip, CSR_CMD, CUC_STATS_RST);
1035         (void) GET8(ip, CSR_CMD);       /* flush wb */
1036 
1037         for (i = 10000; i; i -= 10) {
1038                 SYNCSTATS(sp, 0, 0, DDI_DMA_SYNC_FORKERNEL);
1039                 if (GETSTAT(sp, STATS_DONE_OFFSET) == STATS_RST_DONE) {
1040                         /* yay stats are updated */
1041                         break;


1157 iprb_rx(iprb_t *ip)
1158 {
1159         iprb_dma_t      *rfd;
1160         uint16_t        cnt;
1161         uint16_t        sts;
1162         int             i;
1163         mblk_t          *mplist;
1164         mblk_t          **mpp;
1165         mblk_t          *mp;
1166 
1167         mplist = NULL;
1168         mpp = &mplist;
1169 
1170         for (i = 0; i < NUM_RX; i++) {
1171                 rfd = &ip->rxb[ip->rx_index];
1172                 SYNCRFD(rfd, RFD_STS_OFFSET, 2, DDI_DMA_SYNC_FORKERNEL);
1173                 if ((GETRFD16(rfd, RFD_STS_OFFSET) & RFD_STS_C) == 0) {
1174                         break;
1175                 }
1176 
1177                 ip->rx_wdog = gethrtime();
1178 
1179                 SYNCRFD(rfd, 0, 0, DDI_DMA_SYNC_FORKERNEL);
1180                 cnt = GETRFD16(rfd, RFD_CNT_OFFSET);
1181                 cnt &= ~(RFD_CNT_EOF | RFD_CNT_F);
1182                 sts = GETRFD16(rfd, RFD_STS_OFFSET);
1183 
1184                 if (cnt > (ETHERMAX + VLAN_TAGSZ)) {
1185                         ip->toolong++;
1186                         iprb_rx_add(ip);
1187                         continue;
1188                 }
1189                 if (((sts & RFD_STS_OK) == 0) && (sts & RFD_STS_ERRS)) {
1190                         iprb_rx_add(ip);
1191                         continue;
1192                 }
1193                 if ((mp = allocb(cnt, BPRI_MED)) == NULL) {
1194                         ip->norcvbuf++;
1195                         iprb_rx_add(ip);
1196                         continue;
1197                 }


1646 
1647 void
1648 iprb_periodic(void *arg)
1649 {
1650         iprb_t *ip = arg;
1651         boolean_t reset = B_FALSE;
1652 
1653         mutex_enter(&ip->rulock);
1654         if (ip->suspended || !ip->running) {
1655                 mutex_exit(&ip->rulock);
1656                 return;
1657         }
1658 
1659         /*
1660          * If we haven't received a packet in a while, and if the link
1661          * is up, then it might be a hung chip.  This problem
1662          * reportedly only occurs at 10 Mbps.
1663          */
1664         if (ip->rxhangbug &&
1665             ((ip->miih == NULL) || (mii_get_speed(ip->miih) == 10000000)) &&
1666             ((gethrtime() - ip->rx_wdog) > ip->rx_timeout)) {
1667                 cmn_err(CE_CONT, "?Possible RU hang, resetting.\n");
1668                 reset = B_TRUE;
1669         }
1670 
1671         /* update the statistics */
1672         mutex_enter(&ip->culock);
1673 
1674         if (ip->tx_wdog && ((gethrtime() - ip->tx_wdog) > ip->tx_timeout)) {
1675                 /* transmit/CU hang? */
1676                 cmn_err(CE_CONT, "?CU stalled, resetting.\n");
1677                 reset = B_TRUE;
1678         }
1679 
1680         if (reset) {
1681                 /* We want to reconfigure */
1682                 iprb_stop(ip);
1683                 if (iprb_start(ip) != DDI_SUCCESS) {
1684                         iprb_error(ip, "unable to restart chip");
1685                 }
1686         }
1687 
1688         iprb_update_stats(ip);
1689 
1690         mutex_exit(&ip->culock);
1691         mutex_exit(&ip->rulock);
1692 }
1693 
1694 int