Changeset 7b865a4 in rtems


Ignore:
Timestamp:
Aug 16, 2012, 1:55:03 PM (7 years ago)
Author:
Christian Mauderer <christian.mauderer@…>
Branches:
4.11, master
Children:
3913e3cf
Parents:
f9fe954
git-author:
Christian Mauderer <christian.mauderer@…> (08/16/12 13:55:03)
git-committer:
Sebastian Huber <sebastian.huber@…> (08/21/12 09:06:24)
Message:

bsp/mpc55xx: Use a one second timeout

File:
1 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/powerpc/mpc55xxevb/network/smsc9218i.c

    rf9fe954 r7b865a4  
    133133  SMSC9218I_RUNNING
    134134} smsc9218i_state;
     135
     136static const char *const state_to_string [] = {
     137  "NOT INITIALIZED",
     138  "CONFIGURED",
     139  "STARTED",
     140  "RUNNING"
     141};
    135142
    136143typedef struct {
     
    224231};
    225232
    226 static void smsc9218i_mac_wait(volatile smsc9218i_registers *regs)
    227 {
    228   while ((regs->mac_csr_cmd & SMSC9218I_MAC_CSR_CMD_BUSY) != 0) {
     233static rtems_interval smsc9218i_timeout_init(void)
     234{
     235  return rtems_clock_get_ticks_since_boot();
     236}
     237
     238static bool smsc9218i_timeout_not_expired(rtems_interval start)
     239{
     240  rtems_interval elapsed = rtems_clock_get_ticks_since_boot() - start;
     241
     242  return elapsed < rtems_clock_get_ticks_per_second();
     243}
     244
     245static bool smsc9218i_mac_wait(volatile smsc9218i_registers *regs)
     246{
     247  rtems_interval start = smsc9218i_timeout_init();
     248  bool busy;
     249
     250  while (
     251    (busy = (regs->mac_csr_cmd & SMSC9218I_MAC_CSR_CMD_BUSY) != 0)
     252      && smsc9218i_timeout_not_expired(start)
     253  ) {
    229254    /* Wait */
    230255  }
    231 }
    232 
    233 static void smsc9218i_mac_write(
     256
     257  return !busy;
     258}
     259
     260static bool smsc9218i_mac_write(
    234261  volatile smsc9218i_registers *regs,
    235262  uint32_t address,
     
    237264)
    238265{
    239   smsc9218i_mac_wait(regs);
    240   regs->mac_csr_data = SMSC9218I_SWAP(data);
    241   regs->mac_csr_cmd = SMSC9218I_MAC_CSR_CMD_BUSY
    242     | SMSC9218I_MAC_CSR_CMD_ADDR(address);
    243   smsc9218i_mac_wait(regs);
     266  bool ok = smsc9218i_mac_wait(regs);
     267
     268  if (ok) {
     269    regs->mac_csr_data = SMSC9218I_SWAP(data);
     270    regs->mac_csr_cmd = SMSC9218I_MAC_CSR_CMD_BUSY
     271      | SMSC9218I_MAC_CSR_CMD_ADDR(address);
     272    ok = smsc9218i_mac_wait(regs);
     273  }
     274
     275  return ok;
    244276}
    245277
    246278static uint32_t smsc9218i_mac_read(
    247279  volatile smsc9218i_registers *regs,
    248   uint32_t address
     280  uint32_t address,
     281  bool *ok_ptr
    249282)
    250283{
    251284  uint32_t mac_csr_data = 0;
    252 
    253   smsc9218i_mac_wait(regs);
    254   regs->mac_csr_cmd = SMSC9218I_MAC_CSR_CMD_BUSY
    255     | SMSC9218I_MAC_CSR_CMD_READ
    256     | SMSC9218I_MAC_CSR_CMD_ADDR(address);
    257   smsc9218i_mac_wait(regs);
    258   mac_csr_data = regs->mac_csr_data;
     285  bool ok = smsc9218i_mac_wait(regs);
     286
     287  if (ok) {
     288    regs->mac_csr_cmd = SMSC9218I_MAC_CSR_CMD_BUSY
     289      | SMSC9218I_MAC_CSR_CMD_READ
     290      | SMSC9218I_MAC_CSR_CMD_ADDR(address);
     291    ok = smsc9218i_mac_wait(regs);
     292
     293    if (ok) {
     294      mac_csr_data = regs->mac_csr_data;
     295    }
     296  }
     297
     298  if (ok_ptr != NULL) {
     299    *ok_ptr = ok;
     300  }
    259301
    260302  return SMSC9218I_SWAP(mac_csr_data);
    261303}
    262304
    263 static void smsc9218i_phy_wait(volatile smsc9218i_registers *regs)
    264 {
    265   uint32_t mac_mii_acc = 0;
     305static bool smsc9218i_phy_wait(volatile smsc9218i_registers *regs)
     306{
     307  rtems_interval start = smsc9218i_timeout_init();
     308  uint32_t mac_mii_acc;
     309  bool busy;
    266310
    267311  do {
    268     mac_mii_acc = smsc9218i_mac_read(regs, SMSC9218I_MAC_MII_ACC);
    269   } while ((mac_mii_acc & SMSC9218I_MAC_MII_ACC_BUSY) != 0);
    270 }
    271 
    272 static void smsc9218i_phy_write(
     312    mac_mii_acc = smsc9218i_mac_read(regs, SMSC9218I_MAC_MII_ACC, NULL);
     313  } while (
     314    (busy = (mac_mii_acc & SMSC9218I_MAC_MII_ACC_BUSY) != 0)
     315      && smsc9218i_timeout_not_expired(start)
     316  );
     317
     318  return !busy;
     319}
     320
     321static bool smsc9218i_phy_write(
    273322  volatile smsc9218i_registers *regs,
    274323  uint32_t address,
     
    276325)
    277326{
    278   smsc9218i_phy_wait(regs);
    279   smsc9218i_mac_write(regs, SMSC9218I_MAC_MII_DATA, data);
    280   smsc9218i_mac_write(
    281     regs,
    282     SMSC9218I_MAC_MII_ACC,
    283     SMSC9218I_MAC_MII_ACC_PHY_DEFAULT
    284       | SMSC9218I_MAC_MII_ACC_BUSY
    285       | SMSC9218I_MAC_MII_ACC_WRITE
    286       | SMSC9218I_MAC_MII_ACC_ADDR(address)
    287   );
    288   smsc9218i_phy_wait(regs);
     327  bool ok = smsc9218i_phy_wait(regs);
     328
     329  if (ok) {
     330    ok = smsc9218i_mac_write(regs, SMSC9218I_MAC_MII_DATA, data);
     331
     332    if (ok) {
     333      ok = smsc9218i_mac_write(
     334        regs,
     335        SMSC9218I_MAC_MII_ACC,
     336        SMSC9218I_MAC_MII_ACC_PHY_DEFAULT
     337          | SMSC9218I_MAC_MII_ACC_BUSY
     338          | SMSC9218I_MAC_MII_ACC_WRITE
     339          | SMSC9218I_MAC_MII_ACC_ADDR(address)
     340      );
     341
     342      if (ok) {
     343        ok = smsc9218i_phy_wait(regs);
     344      }
     345    }
     346  }
     347
     348  return ok;
    289349}
    290350
     
    303363  );
    304364  smsc9218i_phy_wait(regs);
    305   return smsc9218i_mac_read(regs, SMSC9218I_MAC_MII_DATA);
    306 }
    307 
    308 static void smsc9218i_enable_promiscous_mode(
     365  return smsc9218i_mac_read(regs, SMSC9218I_MAC_MII_DATA, NULL);
     366}
     367
     368static bool smsc9218i_enable_promiscous_mode(
    309369  volatile smsc9218i_registers *regs,
    310370  bool enable
    311371)
    312372{
    313   uint32_t flags = SMSC9218I_MAC_CR_RXALL | SMSC9218I_MAC_CR_PRMS;
    314   uint32_t mac_cr = smsc9218i_mac_read(regs, SMSC9218I_MAC_CR);
    315 
    316   if (enable) {
    317     mac_cr |= flags;
    318   } else {
    319     mac_cr &= ~flags;
    320   }
    321 
    322   smsc9218i_mac_write(regs, SMSC9218I_MAC_CR, mac_cr);
     373  bool ok;
     374  uint32_t mac_cr = smsc9218i_mac_read(regs, SMSC9218I_MAC_CR, &ok);
     375
     376  if (ok) {
     377    uint32_t flags = SMSC9218I_MAC_CR_RXALL | SMSC9218I_MAC_CR_PRMS;
     378
     379    if (enable) {
     380      mac_cr |= flags;
     381    } else {
     382      mac_cr &= ~flags;
     383    }
     384
     385    ok = smsc9218i_mac_write(regs, SMSC9218I_MAC_CR, mac_cr);
     386  }
     387
     388  return ok;
    323389}
    324390
     
    566632  rtems_status_code sc = RTEMS_SUCCESSFUL;
    567633  smsc9218i_driver_entry *e = &smsc9218i_driver_data;
    568   volatile smsc9218i_registers *const regs = smsc9218i;
    569634  smsc9218i_receive_job_control *jc = &smsc_rx_jc;
    570635
     
    737802
    738803  media_ok = smsc9218i_media_status(e, &media);
    739   mac_cr = smsc9218i_mac_read(regs, SMSC9218I_MAC_CR);
     804  mac_cr = smsc9218i_mac_read(regs, SMSC9218I_MAC_CR, NULL);
    740805  if (media_ok && (IFM_OPTIONS(media) & IFM_FDX) == 0) {
    741806    mac_cr &= ~SMSC9218I_MAC_CR_FDPX;
     
    858923
    859924  /* Enable MAC receiver */
    860   mac_cr = smsc9218i_mac_read(regs, SMSC9218I_MAC_CR);
     925  mac_cr = smsc9218i_mac_read(regs, SMSC9218I_MAC_CR, NULL);
    861926  mac_cr |= SMSC9218I_MAC_CR_RXEN;
    862927  smsc9218i_mac_write(regs, SMSC9218I_MAC_CR, mac_cr);
     
    13911456
    13921457  /* Enable MAC transmitter */
    1393   mac_cr = smsc9218i_mac_read(regs, SMSC9218I_MAC_CR) | SMSC9218I_MAC_CR_TXEN;
     1458  mac_cr = smsc9218i_mac_read(regs, SMSC9218I_MAC_CR, NULL) | SMSC9218I_MAC_CR_TXEN;
    13941459  smsc9218i_mac_write(regs, SMSC9218I_MAC_CR, mac_cr);
    13951460
     
    14681533#endif
    14691534
    1470 static void smsc9218i_wait_for_eeprom_access(volatile smsc9218i_registers *regs)
    1471 {
    1472   while ((regs->e2p_cmd & SMSC9218I_E2P_CMD_EPC_BUSY) != 0) {
     1535static bool smsc9218i_wait_for_eeprom_access(
     1536  volatile smsc9218i_registers *regs
     1537)
     1538{
     1539  rtems_interval start = smsc9218i_timeout_init();
     1540  bool busy;
     1541
     1542  while (
     1543    (busy = (regs->e2p_cmd & SMSC9218I_E2P_CMD_EPC_BUSY) != 0)
     1544      && smsc9218i_timeout_not_expired(start)
     1545  ) {
    14731546    /* Wait */
    14741547  }
    1475 }
    1476 
    1477 static void smsc9218i_set_mac_address(
     1548
     1549  return !busy;
     1550}
     1551
     1552static bool smsc9218i_set_mac_address(
    14781553  volatile smsc9218i_registers *regs,
    14791554  unsigned char address [6]
    14801555)
    14811556{
    1482   smsc9218i_mac_write(
     1557  bool ok = smsc9218i_mac_write(
    14831558    regs,
    14841559    SMSC9218I_MAC_ADDRL,
     
    14861561      | ((uint32_t) address [1] << 8) | (uint32_t) address [0]
    14871562  );
    1488   smsc9218i_mac_write(
    1489     regs,
    1490     SMSC9218I_MAC_ADDRH,
    1491     ((uint32_t) address [5] << 8) | (uint32_t) address [4]
    1492   );
     1563
     1564  if (ok) {
     1565    ok = smsc9218i_mac_write(
     1566      regs,
     1567      SMSC9218I_MAC_ADDRH,
     1568      ((uint32_t) address [5] << 8) | (uint32_t) address [4]
     1569    );
     1570  }
     1571
     1572  return ok;
    14931573}
    14941574
     
    14961576static void smsc9218i_mac_address_dump(volatile smsc9218i_registers *regs)
    14971577{
    1498   uint32_t low = smsc9218i_mac_read(regs, SMSC9218I_MAC_ADDRL);
    1499   uint32_t high = smsc9218i_mac_read(regs, SMSC9218I_MAC_ADDRH);
     1578  uint32_t low = smsc9218i_mac_read(regs, SMSC9218I_MAC_ADDRL, NULL);
     1579  uint32_t high = smsc9218i_mac_read(regs, SMSC9218I_MAC_ADDRH, NULL);
    15001580
    15011581  printf(
     
    16311711}
    16321712
    1633 static void smsc9218i_hardware_reset(volatile smsc9218i_registers *regs)
    1634 {
     1713static bool smsc9218i_hardware_reset(volatile smsc9218i_registers *regs)
     1714{
     1715  rtems_interval start = smsc9218i_timeout_init();
     1716  bool not_ready;
     1717
    16351718  smsc9218i_reset_signal_init();
    16361719  smsc9218i_reset_signal(false);
     
    16381721  smsc9218i_reset_signal(true);
    16391722
    1640   while ((regs->pmt_ctrl & SMSC9218I_PMT_CTRL_READY) == 0) {
     1723  while (
     1724    (not_ready = (regs->pmt_ctrl & SMSC9218I_PMT_CTRL_READY) == 0)
     1725      && smsc9218i_timeout_not_expired(start)
     1726  ) {
    16411727    /* Wait */
    16421728  }
     1729
     1730  return !not_ready;
    16431731}
    16441732
     
    16481736  struct ifnet *ifp = &e->arpcom.ac_if;
    16491737  volatile smsc9218i_registers *const regs = smsc9218i;
     1738  bool ok = true;
    16501739
    16511740  SMSC9218I_PRINTF("%s\n", __func__);
    16521741
    16531742  if (e->state == SMSC9218I_CONFIGURED) {
    1654     smsc9218i_hardware_reset(regs);
    1655 
     1743    ok = smsc9218i_hardware_reset(regs);
     1744    if (ok) {
     1745      e->state = SMSC9218I_NOT_INITIALIZED;
     1746    }
     1747  }
     1748
     1749  if (e->state == SMSC9218I_NOT_INITIALIZED) {
    16561750#if defined(DEBUG)
    1657     /* Register dump */
    16581751    smsc9218i_register_dump(regs);
    16591752#endif
     
    16621755    regs->hw_cfg = SMSC9218I_HW_CFG_MBO | SMSC9218I_HW_CFG_TX_FIF_SZ(5);
    16631756
    1664     /* MAC address */
    1665     smsc9218i_wait_for_eeprom_access(regs);
    1666     smsc9218i_set_mac_address(regs, e->arpcom.ac_enaddr);
     1757    ok = smsc9218i_wait_for_eeprom_access(regs);
     1758
     1759    if (ok) {
     1760      ok = smsc9218i_set_mac_address(regs, e->arpcom.ac_enaddr);
     1761
     1762      if (ok) {
    16671763#if defined(DEBUG)
    1668     smsc9218i_mac_address_dump(regs);
     1764        smsc9218i_mac_address_dump(regs);
    16691765#endif
    16701766
    1671     /* Auto-negotiation advertisment */
    1672     smsc9218i_phy_write(
    1673       regs,
    1674       MII_ANAR,
    1675       ANAR_TX_FD | ANAR_TX | ANAR_10_FD | ANAR_10 | ANAR_CSMA
    1676     );
    1677 
     1767        /* Auto-negotiation advertisment */
     1768        ok = smsc9218i_phy_write(
     1769          regs,
     1770          MII_ANAR,
     1771          ANAR_TX_FD | ANAR_TX | ANAR_10_FD | ANAR_10 | ANAR_CSMA
     1772        );
     1773
     1774        if (ok) {
    16781775#ifdef SMSC9218I_ENABLE_LED_OUTPUTS
    1679     regs->gpio_cfg = SMSC9218I_HW_CFG_LED_1
    1680       | SMSC9218I_HW_CFG_LED_2
    1681       | SMSC9218I_HW_CFG_LED_3;
     1776          regs->gpio_cfg = SMSC9218I_HW_CFG_LED_1
     1777            | SMSC9218I_HW_CFG_LED_2
     1778            | SMSC9218I_HW_CFG_LED_3;
    16821779#endif
    16831780
    1684     /* Initialize interrupts */
    1685     smsc9218i_interrupt_init(e, regs);
    1686 
    1687     /* Set MAC control */
    1688     smsc9218i_mac_write(regs, SMSC9218I_MAC_CR, SMSC9218I_MAC_CR_FDPX);
    1689 
    1690     /* Set FIFO interrupts */
    1691     regs->fifo_int = SMSC9218I_FIFO_INT_TDAL(32);
    1692 
    1693     /* Clear receive drop counter */
    1694     regs->rx_drop;
    1695 
    1696     /* Start receive task */
    1697     if (e->receive_task == RTEMS_ID_NONE) {
    1698       e->receive_task = rtems_bsdnet_newproc(
    1699         "ntrx",
    1700         4096,
    1701         smsc9218i_receive_task,
    1702         e
    1703       );
    1704     }
    1705 
    1706     /* Start transmit task */
    1707     if (e->transmit_task == RTEMS_ID_NONE) {
    1708       e->transmit_task = rtems_bsdnet_newproc(
    1709         "nttx",
    1710         4096,
    1711         smsc9218i_transmit_task,
    1712         e
    1713       );
    1714     }
    1715 
    1716     /* Change state */
    1717     if (e->receive_task != RTEMS_ID_NONE
    1718       && e->transmit_task != RTEMS_ID_NONE) {
    1719       e->state = SMSC9218I_STARTED;
     1781          smsc9218i_interrupt_init(e, regs);
     1782
     1783          /* Set MAC control */
     1784          ok = smsc9218i_mac_write(regs, SMSC9218I_MAC_CR, SMSC9218I_MAC_CR_FDPX);
     1785          if (ok) {
     1786            /* Set FIFO interrupts */
     1787            regs->fifo_int = SMSC9218I_FIFO_INT_TDAL(32);
     1788
     1789            /* Clear receive drop counter */
     1790            regs->rx_drop;
     1791
     1792            /* Start receive task */
     1793            if (e->receive_task == RTEMS_ID_NONE) {
     1794              e->receive_task = rtems_bsdnet_newproc(
     1795                "ntrx",
     1796                4096,
     1797                smsc9218i_receive_task,
     1798                e
     1799              );
     1800            }
     1801
     1802            /* Start transmit task */
     1803            if (e->transmit_task == RTEMS_ID_NONE) {
     1804              e->transmit_task = rtems_bsdnet_newproc(
     1805                "nttx",
     1806                4096,
     1807                smsc9218i_transmit_task,
     1808                e
     1809              );
     1810            }
     1811
     1812            /* Change state */
     1813            if (e->receive_task != RTEMS_ID_NONE
     1814              && e->transmit_task != RTEMS_ID_NONE) {
     1815              e->state = SMSC9218I_STARTED;
     1816            }
     1817          }
     1818        }
     1819      }
    17201820    }
    17211821  }
     
    17231823  if (e->state == SMSC9218I_STARTED) {
    17241824    /* Enable promiscous mode */
    1725     smsc9218i_enable_promiscous_mode(
     1825    ok = smsc9218i_enable_promiscous_mode(
    17261826      regs,
    17271827      (ifp->if_flags & IFF_PROMISC) != 0
    17281828    );
    17291829
    1730     /* Set interface to running state */
    1731     ifp->if_flags |= IFF_RUNNING;
    1732 
    1733     /* Change state */
    1734     e->state = SMSC9218I_RUNNING;
     1830    if (ok) {
     1831      /* Set interface to running state */
     1832      ifp->if_flags |= IFF_RUNNING;
     1833
     1834      /* Change state */
     1835      e->state = SMSC9218I_RUNNING;
     1836    }
    17351837  }
    17361838}
     
    17991901  printf("transmit DMA errors:       %u\n", e->transmit_dma_errors);
    18001902  printf("frame compact count:       %u\n", jc->frame_compact_count);
     1903  printf("interface state:           %s\n", state_to_string [e->state]);
    18011904}
    18021905
     
    18051908  smsc9218i_driver_entry *e = (smsc9218i_driver_entry *) ifp->if_softc;
    18061909  rtems_status_code sc = RTEMS_SUCCESSFUL;
    1807   rtems_interrupt_level level;
    1808   union SIU_DIRER_tag direr = MPC55XX_ZERO_FLAGS;
    18091910
    18101911  /* remove interrupt handler */
     
    18491950    case SIOCSIFFLAGS:
    18501951      if (ifp->if_flags & IFF_UP) {
    1851         ifp->if_flags |= IFF_RUNNING;
    18521952        /* TODO: init */
    18531953      } else {
    1854         smsc9218i_interface_off(ifp);
     1954        smsc9218i_interface_off(ifp);
    18551955      }
    18561956      break;
Note: See TracChangeset for help on using the changeset viewer.