Changeset c5c5a19 in rtems-libbsd


Ignore:
Timestamp:
06/22/22 13:39:15 (8 weeks ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
6-freebsd-12
Children:
9a88b07
Parents:
1056349
git-author:
Sebastian Huber <sebastian.huber@…> (06/22/22 13:39:15)
git-committer:
Sebastian Huber <sebastian.huber@…> (06/24/22 05:33:29)
Message:

if_lpe.c: Use interface transmit

This avoids the need for a transmit task and transmit interrupts.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • rtemsbsd/sys/arm/lpc/if_lpe.c

    r1056349 rc5c5a19  
    88
    99/*
    10  * Copyright (c) 2009-2012 embedded brains GmbH.  All rights reserved.
    11  *
    12  *  embedded brains GmbH
    13  *  Obere Lagerstr. 30
    14  *  82178 Puchheim
    15  *  Germany
    16  *  <rtems@embedded-brains.de>
     10 * Copyright (C) 2009, 2022 embedded brains GmbH
    1711 *
    1812 * The license and distribution terms for this file may be
     
    265259#define LPC_ETH_EVENT_INIT_TX RTEMS_EVENT_1
    266260
    267 #define LPC_ETH_EVENT_TXSTART RTEMS_EVENT_2
    268 
    269261#define LPC_ETH_EVENT_INTERRUPT RTEMS_EVENT_3
    270262
     
    275267#define LPC_ETH_INTERRUPT_RECEIVE \
    276268  (ETH_INT_RX_ERROR | ETH_INT_RX_FINISHED | ETH_INT_RX_DONE)
    277 
    278 #define LPC_ETH_INTERRUPT_TRANSMIT \
    279   (ETH_INT_TX_DONE | ETH_INT_TX_FINISHED | ETH_INT_TX_ERROR)
    280269
    281270#define LPC_ETH_RX_STAT_ERRORS \
     
    318307  struct callout watchdog_callout;
    319308  rtems_id receive_task;
    320   rtems_id transmit_task;
    321309  unsigned rx_unit_count;
    322310  unsigned tx_unit_count;
     
    332320  unsigned receive_interrupts;
    333321  unsigned transmitted_frames;
    334   unsigned transmit_interrupts;
    335322  unsigned receive_drop_errors;
    336323  unsigned receive_overrun_errors;
     
    436423    re = LPC_ETH_EVENT_INTERRUPT;
    437424    ie |= LPC_ETH_INTERRUPT_RECEIVE;
     425    ++e->receive_interrupts;
    438426  }
    439427
    440428  /* Send events to receive task */
    441429  if (re != 0) {
    442     ++e->receive_interrupts;
    443430    (void) rtems_event_send(e->receive_task, re);
    444   }
    445 
    446   /* Check transmit interrupts */
    447   if ((is & LPC_ETH_INTERRUPT_TRANSMIT) != 0) {
    448     te = LPC_ETH_EVENT_INTERRUPT;
    449     ie |= LPC_ETH_INTERRUPT_TRANSMIT;
    450   }
    451 
    452   /* Send events to transmit task */
    453   if (te != 0) {
    454     ++e->transmit_interrupts;
    455     (void) rtems_event_send(e->transmit_task, te);
    456431  }
    457432
     
    480455  rtems_interrupt_disable(level);
    481456  lpc_eth->intenable &= ~LPC_ETH_INTERRUPT_RECEIVE;
    482   rtems_interrupt_enable(level);
    483 }
    484 
    485 static void lpc_eth_enable_transmit_interrupts(void)
    486 {
    487   rtems_interrupt_level level;
    488 
    489   rtems_interrupt_disable(level);
    490   lpc_eth->intenable |= LPC_ETH_INTERRUPT_TRANSMIT;
    491   rtems_interrupt_enable(level);
    492 }
    493 
    494 static void lpc_eth_disable_transmit_interrupts(void)
    495 {
    496   rtems_interrupt_level level;
    497 
    498   rtems_interrupt_disable(level);
    499   lpc_eth->intenable &= ~LPC_ETH_INTERRUPT_TRANSMIT;
    500457  rtems_interrupt_enable(level);
    501458}
     
    513470  uint32_t produce_index;
    514471
    515   /* Disable transmit interrupts */
    516   lpc_eth_disable_transmit_interrupts();
    517 
    518472  /* Disable transmitter */
    519473  lpc_eth->command &= ~ETH_CMD_TX_ENABLE;
     
    526480  /* Reset */
    527481  lpc_eth->command |= ETH_CMD_TX_RESET;
    528 
    529   /* Clear transmit interrupts */
    530   lpc_eth->intclear = LPC_ETH_INTERRUPT_TRANSMIT;
    531482
    532483  /* Transmit descriptors */
     
    538489    /* Discard outstanding fragments (= data loss) */
    539490    for (produce_index = 0; produce_index <= index_max; ++produce_index) {
    540       struct mbuf *victim = mbufs [produce_index];
    541 
    542       if (victim != NULL) {
    543         m_free(victim);
    544         mbufs [produce_index] = NULL;
    545       }
     491      m_freem(mbufs [produce_index]);
     492      mbufs [produce_index] = NULL;
    546493    }
    547494  #else
     
    816763)
    817764{
    818   struct mbuf *n = NULL;
    819   int size = 0;
     765  struct mbuf *n;
     766  int size;
    820767
    821768  while (true) {
    822     if (m == NULL) {
    823       /* Dequeue first fragment of the next frame */
    824       IF_DEQUEUE(&ifp->if_snd, m);
    825 
    826       /* Empty queue? */
    827       if (m == NULL) {
    828         return m;
    829       }
    830     }
    831 
    832769    /* Get fragment size */
    833770    size = m->m_len;
     
    837774      break;
    838775    } else {
    839       /* Discard empty fragments */
    840       m = m_free(m);
     776      /* Skip empty fragments */
     777      m = m->m_next;
     778
     779      if (m == NULL) {
     780        return NULL;
     781      }
    841782    }
    842783  }
     
    860801}
    861802
    862 static void lpc_eth_transmit_task(rtems_task_argument arg)
    863 {
    864   rtems_status_code sc = RTEMS_SUCCESSFUL;
    865   rtems_event_set events = 0;
    866   lpc_eth_driver_entry *e = (lpc_eth_driver_entry *) arg;
    867   struct ifnet *ifp = e->ifp;
     803static void lpc_eth_tx_reclaim(lpc_eth_driver_entry *e, struct ifnet *ifp)
     804{
     805  volatile uint32_t *const status = e->tx_status_table;
    868806  volatile lpc_eth_transfer_descriptor *const desc = e->tx_desc_table;
    869   volatile uint32_t *const status = e->tx_status_table;
    870807  #ifdef LPC_ETH_CONFIG_USE_TRANSMIT_DMA
    871808    struct mbuf **const mbufs = e->tx_buf_table;
     
    873810    char *const buf = e->tx_buf_table;
    874811  #endif
    875   struct mbuf *m = NULL;
    876812  uint32_t const index_max = e->tx_unit_count - 1;
    877   uint32_t ctrl = 0;
    878 
    879   LPC_ETH_PRINTF("%s\n", __func__);
    880 
    881   /* Main event loop */
     813  uint32_t consume_index = e->tx_consume_index;
     814
     815  /* Free consumed fragments */
    882816  while (true) {
    883     uint32_t produce_index;
    884     uint32_t consume_index;
    885     #ifndef LPC_ETH_CONFIG_USE_TRANSMIT_DMA
    886       uint32_t frame_length;
    887       char *frame_buffer;
    888     #endif
    889 
    890     /* Wait for events */
    891     sc = rtems_event_receive(
    892       LPC_ETH_EVENT_STOP
    893         | LPC_ETH_EVENT_TXSTART
    894         | LPC_ETH_EVENT_INTERRUPT,
    895       RTEMS_EVENT_ANY | RTEMS_WAIT,
    896       RTEMS_NO_TIMEOUT,
    897       &events
    898     );
    899     BSD_ASSERT(sc == RTEMS_SUCCESSFUL);
    900 
    901     LPC_ETH_PRINTF("tx: wake up: 0x%08" PRIx32 "\n", events);
    902 
    903     /* Stop transmitter? */
    904     if ((events & LPC_ETH_EVENT_STOP) != 0) {
    905       lpc_eth_control_request_complete(e);
    906 
    907       /* Wait for events */
    908       continue;
    909     }
    910 
    911     LPE_LOCK(e);
    912 
    913     /* Get indices */
    914     produce_index = e->tx_produce_index;
    915     consume_index = e->tx_consume_index;
    916 
    917     #ifndef LPC_ETH_CONFIG_USE_TRANSMIT_DMA
    918       /* Fresh frame length and buffer start */
    919       frame_length = 0;
    920       frame_buffer = (char *) desc [produce_index].start;
    921     #endif
    922 
    923     /* Free consumed fragments */
    924     while (true) {
    925       /* Save last known consume index */
    926       uint32_t c = consume_index;
    927 
    928       /* Clear transmit interrupt status */
    929       lpc_eth->intclear = LPC_ETH_INTERRUPT_TRANSMIT;
    930 
    931       /* Get new consume index */
    932       consume_index = lpc_eth->txconsumeindex;
    933 
    934       /* Nothing consumed in the meantime? */
    935       if (c == consume_index) {
    936         break;
     817    /* Save last known consume index */
     818    uint32_t c = consume_index;
     819
     820    /* Get new consume index */
     821    consume_index = lpc_eth->txconsumeindex;
     822
     823    /* Nothing consumed in the meantime? */
     824    if (c == consume_index) {
     825      break;
     826    }
     827
     828    while (c != consume_index) {
     829      uint32_t s = status [c];
     830
     831      /* Update error counters */
     832      if ((s & (ETH_TX_STAT_ERROR | ETH_TX_STAT_NO_DESCRIPTOR)) != 0) {
     833        if ((s & ETH_TX_STAT_UNDERRUN) != 0) {
     834          ++e->transmit_underrun_errors;
     835        }
     836        if ((s & ETH_TX_STAT_LATE_COLLISION) != 0) {
     837          ++e->transmit_late_collision_errors;
     838        }
     839        if ((s & ETH_TX_STAT_EXCESSIVE_COLLISION) != 0) {
     840          ++e->transmit_excessive_collision_errors;
     841        }
     842        if ((s & ETH_TX_STAT_EXCESSIVE_DEFER) != 0) {
     843          ++e->transmit_excessive_defer_errors;
     844        }
     845        if ((s & ETH_TX_STAT_NO_DESCRIPTOR) != 0) {
     846          ++e->transmit_no_descriptor_errors;
     847        }
    937848      }
    938849
    939       while (c != consume_index) {
    940         uint32_t s = status [c];
    941 
    942         /* Update error counters */
    943         if ((s & (ETH_TX_STAT_ERROR | ETH_TX_STAT_NO_DESCRIPTOR)) != 0) {
    944           if ((s & ETH_TX_STAT_UNDERRUN) != 0) {
    945             ++e->transmit_underrun_errors;
    946           }
    947           if ((s & ETH_TX_STAT_LATE_COLLISION) != 0) {
    948             ++e->transmit_late_collision_errors;
    949           }
    950           if ((s & ETH_TX_STAT_EXCESSIVE_COLLISION) != 0) {
    951             ++e->transmit_excessive_collision_errors;
    952           }
    953           if ((s & ETH_TX_STAT_EXCESSIVE_DEFER) != 0) {
    954             ++e->transmit_excessive_defer_errors;
    955           }
    956           if ((s & ETH_TX_STAT_NO_DESCRIPTOR) != 0) {
    957             ++e->transmit_no_descriptor_errors;
    958           }
     850      #ifdef LPC_ETH_CONFIG_USE_TRANSMIT_DMA
     851        /* Release mbuf */
     852        m_freem(mbufs [c]);
     853        mbufs [c] = NULL;
     854      #endif
     855
     856      /* Next consume index */
     857      c = lpc_eth_increment(c, index_max);
     858    }
     859  }
     860
     861  e->tx_consume_index = consume_index;
     862}
     863
     864static int lpc_eth_tx_enqueue(
     865  lpc_eth_driver_entry *e,
     866  struct ifnet *ifp,
     867  struct mbuf *m0
     868)
     869{
     870  volatile lpc_eth_transfer_descriptor *const desc = e->tx_desc_table;
     871  #ifdef LPC_ETH_CONFIG_USE_TRANSMIT_DMA
     872    struct mbuf **const mbufs = e->tx_buf_table;
     873  #else
     874    char *const buf = e->tx_buf_table;
     875    uint32_t frame_length;
     876    char *frame_buffer;
     877  #endif
     878  uint32_t const index_max = e->tx_unit_count - 1;
     879  uint32_t produce_index = e->tx_produce_index;
     880  uint32_t consume_index = e->tx_consume_index;
     881  struct mbuf *m = m0;
     882
     883  while (true) {
     884    uint32_t ctrl;
     885
     886    /* Compute next produce index */
     887    uint32_t p = lpc_eth_increment(produce_index, index_max);
     888
     889    /* Queue full? */
     890    if (p == consume_index) {
     891      LPC_ETH_PRINTF("tx: full queue: 0x%08x\n", m);
     892
     893      /* The queue is full */
     894      return ENOBUFS;
     895    }
     896
     897    /* Get next fragment and control value */
     898    m = lpc_eth_next_fragment(ifp, m, &ctrl);
     899
     900    /* New fragment? */
     901    if (m != NULL) {
     902      #ifdef LPC_ETH_CONFIG_USE_TRANSMIT_DMA
     903        /* Set the transfer data */
     904        rtems_cache_flush_multiple_data_lines(
     905          mtod(m, const void *),
     906          (size_t) m->m_len
     907        );
     908        desc [produce_index].start = mtod(m, uint32_t);
     909        desc [produce_index].control = ctrl;
     910        rtems_cache_flush_multiple_data_lines(
     911          (void *) &desc [produce_index],
     912          sizeof(desc [0])
     913         );
     914
     915        LPC_ETH_PRINTF(
     916          "tx: %02" PRIu32 ": %u %s\n",
     917          produce_index, m->m_len,
     918          (ctrl & ETH_TX_CTRL_LAST) != 0 ? "L" : ""
     919        );
     920
     921        /* Next produce index */
     922        produce_index = p;
     923
     924        /* Last fragment of a frame? */
     925        if ((ctrl & ETH_TX_CTRL_LAST) != 0) {
     926          /* Update the produce index */
     927          lpc_eth->txproduceindex = produce_index;
     928          e->tx_produce_index = produce_index;
     929
     930          mbufs [produce_index] = m0;
     931
     932          /* Increment transmitted frames counter */
     933          ++e->transmitted_frames;
     934
     935          return 0;
    959936        }
    960937
    961         #ifdef LPC_ETH_CONFIG_USE_TRANSMIT_DMA
    962           /* Release mbuf */
    963           m_free(mbufs [c]);
    964           mbufs [c] = NULL;
    965         #endif
    966 
    967         /* Next consume index */
    968         c = lpc_eth_increment(c, index_max);
    969       }
    970     }
    971 
    972     /* Transmit new fragments */
    973     while (true) {
    974       /* Compute next produce index */
    975       uint32_t p = lpc_eth_increment(produce_index, index_max);
    976 
    977       /* Get next fragment and control value */
    978       m = lpc_eth_next_fragment(ifp, m, &ctrl);
    979 
    980       /* Queue full? */
    981       if (p == consume_index) {
    982         LPC_ETH_PRINTF("tx: full queue: 0x%08x\n", m);
    983 
    984         /* The queue is full, wait for transmit interrupt */
    985         break;
    986       }
    987 
    988       /* New fragment? */
    989       if (m != NULL) {
    990         #ifdef LPC_ETH_CONFIG_USE_TRANSMIT_DMA
    991           /* Set the transfer data */
     938        /* Next fragment of the frame */
     939        m = m->m_next;
     940      #else
     941        size_t fragment_length = (size_t) m->m_len;
     942        void *fragment_start = mtod(m, void *);
     943        uint32_t new_frame_length = frame_length + fragment_length;
     944
     945        /* Check buffer size */
     946        if (new_frame_length > LPC_ETH_CONFIG_TX_BUF_SIZE) {
     947          LPC_ETH_PRINTF("tx: overflow\n");
     948
     949          /* Discard overflow data */
     950          new_frame_length = LPC_ETH_CONFIG_TX_BUF_SIZE;
     951          fragment_length = new_frame_length - frame_length;
     952
     953          /* Finalize frame */
     954          ctrl |= LPC_ETH_LAST_FRAGMENT_FLAGS;
     955
     956          /* Update error counter */
     957          ++e->transmit_overflow_errors;
     958        }
     959
     960        LPC_ETH_PRINTF(
     961          "tx: copy: %" PRIu32 "%s%s\n",
     962          fragment_length,
     963          (m->m_flags & M_EXT) != 0 ? ", E" : "",
     964          (m->m_flags & M_PKTHDR) != 0 ? ", H" : ""
     965        );
     966
     967        /* Copy fragment to buffer in Ethernet RAM */
     968        memcpy(frame_buffer, fragment_start, fragment_length);
     969
     970        if ((ctrl & ETH_TX_CTRL_LAST) != 0) {
     971          /* Finalize descriptor */
     972          desc [produce_index].control = (ctrl & ~ETH_TX_CTRL_SIZE_MASK)
     973            | (new_frame_length - 1);
     974
     975          LPC_ETH_PRINTF(
     976            "tx: %02" PRIu32 ": %" PRIu32 "\n",
     977            produce_index,
     978            new_frame_length
     979          );
     980
     981          /* Cache flush of data */
    992982          rtems_cache_flush_multiple_data_lines(
    993             mtod(m, const void *),
    994             (size_t) m->m_len
     983            (const void *) desc [produce_index].start,
     984            new_frame_length
    995985          );
    996           desc [produce_index].start = mtod(m, uint32_t);
    997           desc [produce_index].control = ctrl;
     986
     987          /* Cache flush of descriptor  */
    998988          rtems_cache_flush_multiple_data_lines(
    999989            (void *) &desc [produce_index],
    1000990            sizeof(desc [0])
    1001            );
    1002           mbufs [produce_index] = m;
    1003 
    1004           LPC_ETH_PRINTF(
    1005             "tx: %02" PRIu32 ": %u %s\n",
    1006             produce_index, m->m_len,
    1007             (ctrl & ETH_TX_CTRL_LAST) != 0 ? "L" : ""
    1008991          );
    1009992
     
    1011994          produce_index = p;
    1012995
    1013           /* Last fragment of a frame? */
    1014           if ((ctrl & ETH_TX_CTRL_LAST) != 0) {
    1015             /* Update the produce index */
    1016             lpc_eth->txproduceindex = produce_index;
    1017 
    1018             /* Increment transmitted frames counter */
    1019             ++e->transmitted_frames;
    1020           }
    1021 
    1022           /* Next fragment of the frame */
    1023           m = m->m_next;
    1024         #else
    1025           size_t fragment_length = (size_t) m->m_len;
    1026           void *fragment_start = mtod(m, void *);
    1027           uint32_t new_frame_length = frame_length + fragment_length;
    1028 
    1029           /* Check buffer size */
    1030           if (new_frame_length > LPC_ETH_CONFIG_TX_BUF_SIZE) {
    1031             LPC_ETH_PRINTF("tx: overflow\n");
    1032 
    1033             /* Discard overflow data */
    1034             new_frame_length = LPC_ETH_CONFIG_TX_BUF_SIZE;
    1035             fragment_length = new_frame_length - frame_length;
    1036 
    1037             /* Finalize frame */
    1038             ctrl |= LPC_ETH_LAST_FRAGMENT_FLAGS;
    1039 
    1040             /* Update error counter */
    1041             ++e->transmit_overflow_errors;
    1042           }
    1043 
    1044           LPC_ETH_PRINTF(
    1045             "tx: copy: %" PRIu32 "%s%s\n",
    1046             fragment_length,
    1047             (m->m_flags & M_EXT) != 0 ? ", E" : "",
    1048             (m->m_flags & M_PKTHDR) != 0 ? ", H" : ""
    1049           );
    1050 
    1051           /* Copy fragment to buffer in Ethernet RAM */
    1052           memcpy(frame_buffer, fragment_start, fragment_length);
    1053 
    1054           if ((ctrl & ETH_TX_CTRL_LAST) != 0) {
    1055             /* Finalize descriptor */
    1056             desc [produce_index].control = (ctrl & ~ETH_TX_CTRL_SIZE_MASK)
    1057               | (new_frame_length - 1);
    1058 
    1059             LPC_ETH_PRINTF(
    1060               "tx: %02" PRIu32 ": %" PRIu32 "\n",
    1061               produce_index,
    1062               new_frame_length
    1063             );
    1064 
    1065             /* Cache flush of data */
    1066             rtems_cache_flush_multiple_data_lines(
    1067               (const void *) desc [produce_index].start,
    1068               new_frame_length
    1069             );
    1070 
    1071             /* Cache flush of descriptor  */
    1072             rtems_cache_flush_multiple_data_lines(
    1073               (void *) &desc [produce_index],
    1074               sizeof(desc [0])
    1075             );
    1076 
    1077             /* Next produce index */
    1078             produce_index = p;
    1079 
    1080             /* Update the produce index */
    1081             lpc_eth->txproduceindex = produce_index;
    1082 
    1083             /* Fresh frame length and buffer start */
    1084             frame_length = 0;
    1085             frame_buffer = (char *) desc [produce_index].start;
    1086 
    1087             /* Increment transmitted frames counter */
    1088             ++e->transmitted_frames;
    1089           } else {
    1090             /* New frame length */
    1091             frame_length = new_frame_length;
    1092 
    1093             /* Update current frame buffer start */
    1094             frame_buffer += fragment_length;
    1095           }
    1096 
    1097           /* Free mbuf and get next */
    1098           m = m_free(m);
    1099         #endif
    1100       } else {
    1101         /* Nothing to transmit */
    1102         break;
    1103       }
    1104     }
    1105 
    1106     /* Save indices */
    1107     e->tx_produce_index = produce_index;
    1108     e->tx_consume_index = consume_index;
    1109 
    1110     /* No more fragments? */
    1111     if (m == NULL) {
    1112       /* Interface is now inactive */
    1113       ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
     996          /* Update the produce index */
     997          lpc_eth->txproduceindex = produce_index;
     998
     999          /* Fresh frame length and buffer start */
     1000          frame_length = 0;
     1001          frame_buffer = (char *) desc [produce_index].start;
     1002
     1003          /* Increment transmitted frames counter */
     1004          ++e->transmitted_frames;
     1005        } else {
     1006          /* New frame length */
     1007          frame_length = new_frame_length;
     1008
     1009          /* Update current frame buffer start */
     1010          frame_buffer += fragment_length;
     1011        }
     1012
     1013        /* Free mbuf and get next */
     1014        m = m_free(m);
     1015      #endif
    11141016    } else {
    1115       LPC_ETH_PRINTF("tx: enable interrupts\n");
    1116 
    1117       /* Enable transmit interrupts */
    1118       lpc_eth_enable_transmit_interrupts();
    1119     }
    1120 
    1121     LPE_UNLOCK(e);
     1017      /* Nothing to transmit */
     1018      m_freem(m0);
     1019      return 0;
     1020    }
    11221021  }
    11231022}
     
    14851384    BSD_ASSERT(sc == RTEMS_SUCCESSFUL);
    14861385
    1487     /* Stop tasks */
     1386    /* Stop task */
    14881387    lpc_eth_control_request(e, e->receive_task, LPC_ETH_EVENT_STOP);
    1489     lpc_eth_control_request(e, e->transmit_task, LPC_ETH_EVENT_STOP);
    14901388
    14911389    lpc_eth_soft_reset();
     
    16051503}
    16061504
    1607 static void lpc_eth_interface_start(struct ifnet *ifp)
    1608 {
    1609   rtems_status_code sc = RTEMS_SUCCESSFUL;
     1505static int lpc_eth_interface_transmit(struct ifnet *ifp, struct mbuf *m)
     1506{
    16101507  lpc_eth_driver_entry *e = (lpc_eth_driver_entry *) ifp->if_softc;
    1611 
    1612   ifp->if_drv_flags |= IFF_DRV_OACTIVE;
     1508  int eno;
     1509
     1510  LPE_LOCK(e);
    16131511
    16141512  if (e->state == LPC_ETH_STATE_UP) {
    1615     sc = rtems_event_send(e->transmit_task, LPC_ETH_EVENT_TXSTART);
    1616     BSD_ASSERT(sc == RTEMS_SUCCESSFUL);
    1617   }
     1513    eno = lpc_eth_tx_enqueue(e, ifp, m);
     1514    lpc_eth_tx_reclaim(e, ifp);
     1515
     1516    if (__predict_false(eno != 0)) {
     1517      struct mbuf *n;
     1518
     1519      n = m_defrag(m, M_NOWAIT);
     1520      if (n != NULL) {
     1521        m = n;
     1522      }
     1523
     1524      eno = lpc_eth_tx_enqueue(e, ifp, m);
     1525    }
     1526  } else {
     1527    eno = ENETDOWN;
     1528  }
     1529
     1530  if (eno != 0) {
     1531    m_freem(m);
     1532    if_inc_counter(ifp, IFCOUNTER_OQDROPS, 1);
     1533  }
     1534
     1535  LPE_UNLOCK(e);
     1536  return eno;
    16181537}
    16191538
     
    17731692  ifp->if_init = lpc_eth_interface_init;
    17741693  ifp->if_ioctl = lpc_eth_interface_ioctl;
    1775   ifp->if_start = lpc_eth_interface_start;
     1694  ifp->if_transmit = lpc_eth_interface_transmit;
    17761695  ifp->if_qflush = if_qflush;
    17771696  ifp->if_flags = IFF_BROADCAST | IFF_MULTICAST | IFF_SIMPLEX;
     
    17991718  );
    18001719  BSD_ASSERT(status == RTEMS_SUCCESSFUL);
    1801   status = rtems_task_create(
    1802     rtems_build_name('n', 't', 't', 'x'),
    1803     rtems_bsd_get_task_priority(device_get_name(e->dev)),
    1804     4096,
    1805     RTEMS_DEFAULT_MODES,
    1806     RTEMS_DEFAULT_ATTRIBUTES,
    1807     &e->transmit_task
    1808   );
    1809   BSD_ASSERT(status == RTEMS_SUCCESSFUL);
    1810   status = rtems_task_start(
    1811     e->transmit_task,
    1812     lpc_eth_transmit_task,
    1813     (rtems_task_argument)e
    1814   );
    1815   BSD_ASSERT(status == RTEMS_SUCCESSFUL);
    18161720
    18171721  if_link_state_change(e->ifp, LINK_STATE_UP);
Note: See TracChangeset for help on using the changeset viewer.