From: "oliver.munz" <olimunz@snr.ch>
To: <ecos-patches@sourceware.org>
Subject: at91 emac ethernet driver lwip diff patch
Date: Mon, 20 Apr 2015 11:19:00 -0000 [thread overview]
Message-ID: <a5143a33e2b4952478f8291234b9b4b1@haven.inspiration.ch> (raw)
[-- Attachment #1: Type: text/plain, Size: 170 bytes --]
This is a patch for the at91 emac driver and the lwIP stack.
It should solve the no PBUF leak and other stack blocking errors. It also
replaces some "\t" whit " "...
[-- Attachment #2: at91eth.diff --]
[-- Type: application/octet-stream, Size: 15906 bytes --]
Only in /cygdrive/c/ALL/ecos20150205.olis eth flicks/ecos: eCos.hhc
Only in /cygdrive/c/ALL/ecos20150205.olis eth flicks/ecos: eCos.hhp
diff -r /cygdrive/c/ALL/ecos20150205/ecos/packages/devs/eth/arm/at91/current/src/if_at91.c "/cygdrive/c/ALL/ecos20150205.olis eth flicks/ecos/packages/devs/eth/arm/at91/current/src/if_at91.c"
43,44c43,44
< // Contributors:
< // Date: 2006-05-10
---
> // Contributors: Oliver Munz
> // Date: 2015-04-20
88c88
< #define _eth_drv_init(sc,mac) \
---
> #define _eth_drv_init(sc,mac) \
90c90
< #define _eth_drv_tx_done(sc,key,status) \
---
> #define _eth_drv_tx_done(sc,key,status) \
92c92
< #define _eth_drv_recv(sc,len) \
---
> #define _eth_drv_recv(sc,len) \
517c517
< priv->intr_vector);
---
> priv->intr_vector);
814,827c814,815
< at91_eth_deliver(struct eth_drv_sc *sc)
< {
< at91_eth_priv_t *priv = (at91_eth_priv_t *)sc->driver_private;
<
< cyg_uint32 tsr;
< cyg_uint32 rsr;
<
< cyg_uint32 ctr;
< cyg_uint32 cnt;
< cyg_uint32 idx;
<
< /* Get the Transmit Status */
< HAL_READ_UINT32(priv->base+AT91_EMAC_TSR,tsr);
< HAL_WRITE_UINT32(priv->base+AT91_EMAC_TSR,tsr);
---
> at91_eth_deliver(struct eth_drv_sc *sc) {
> at91_eth_priv_t *priv = (at91_eth_priv_t *) sc->driver_private;
829,831c817,818
< /* Get the Receive Status */
< HAL_READ_UINT32(priv->base+AT91_EMAC_RSR,rsr);
< HAL_WRITE_UINT32(priv->base+AT91_EMAC_RSR,rsr);
---
> cyg_uint32 tsr;
> cyg_uint32 rsr;
832a820,821
> cyg_uint32 cnt;
> cyg_uint32 idx;
834,886c823,917
< //TODO: The interrupts other than RCOMP and TCOMP needs to be
< // handled properly especially stuff like RBNA which could have
< // serious effects on driver performance
<
< /* Service the TX buffers */
< if (tsr&AT91_EMAC_TSR_COL) //1
< {
< debug1_printf("AT91_ETH: Tx COL\n");
< }
<
< if (tsr&AT91_EMAC_TSR_RLE) //2
< {
< debug1_printf("AT91_ETH: Tx RLE\n");
< }
<
< if (tsr&AT91_EMAC_TSR_BNQ) //4
< {
< debug1_printf("AT91_ETH: Tx BEX\n");
< }
<
< if (tsr&AT91_EMAC_TSR_UND) //6
< {
< debug1_printf("AT91_ETH: Tx UND\n");
< }
<
< /* Check that the last transmission is completed */
< if (tsr&AT91_EMAC_TSR_COMP) //5
< {
< at91_reset_tbd(priv);
< _eth_drv_tx_done(sc,priv->curr_tx_key,0);
< priv->tx_busy = false;
< }
<
< /* Service the RX buffers when we get something */
< if (rsr&AT91_EMAC_RSR_REC)
< {
< /* Do this all until we find the first EMAC Buffer */
< while (priv->rbd[priv->curr_rbd_idx].addr & AT91_EMAC_RBD_ADDR_OWNER_SW)
< {
<
< //Firstly walk through to either the first buffer that belongs
< // to the controller or the first SOF
< while ((priv->rbd[priv->curr_rbd_idx].addr &
< AT91_EMAC_RBD_ADDR_OWNER_SW) &&
< !(priv->rbd[priv->curr_rbd_idx].sr &
< AT91_EMAC_RBD_SR_SOF))
< {
< priv->rbd[priv->curr_rbd_idx].addr &=
< ~(AT91_EMAC_RBD_ADDR_OWNER_SW);
< priv->curr_rbd_idx++;
< if (priv->curr_rbd_idx >= CYGNUM_DEVS_ETH_ARM_AT91_RX_BUFS)
< {
< priv->curr_rbd_idx = 0;
---
> /* Get the Transmit Status */
> HAL_READ_UINT32(priv->base+AT91_EMAC_TSR, tsr);
> HAL_WRITE_UINT32(priv->base+AT91_EMAC_TSR, tsr);
>
> /* Get the Receive Status */
> HAL_READ_UINT32(priv->base+AT91_EMAC_RSR, rsr);
> HAL_WRITE_UINT32(priv->base+AT91_EMAC_RSR, rsr);
>
> //TODO: The interrupts other than RCOMP and TCOMP needs to be
> // handled properly especially stuff like RBNA which could have
> // serious effects on driver performance
>
> /* Service the TX buffers */
>
> if (tsr & AT91_EMAC_TSR_COL) //1
> {
> debug1_printf("AT91_ETH: Tx COL\n");
> }
>
> if (tsr & AT91_EMAC_TSR_RLE) //2
> {
> debug1_printf("AT91_ETH: Tx RLE\n");
> }
>
> if (tsr & AT91_EMAC_TSR_BNQ) //4
> {
> debug1_printf("AT91_ETH: Tx BEX\n");
> }
>
> if (tsr & AT91_EMAC_TSR_UND) //6
> {
> debug1_printf("AT91_ETH: Tx UND\n");
> }
>
> /* Check that the last transmission is completed */
> // if (tsr & AT91_EMAC_TSR_COMP) { //5
> #if 1
> if (tsr & (AT91_EMAC_TSR_COMP|AT91_EMAC_TSR_RLE|AT91_EMAC_TSR_BNQ|AT91_EMAC_TSR_UND)) { /* auto retransmit */
> #else
> if (tsr & (AT91_EMAC_TSR_COMP|AT91_EMAC_TSR_RLE|AT91_EMAC_TSR_BNQ|AT91_EMAC_TSR_UND|AT91_EMAC_TSR_COL)) {
> #endif
> at91_reset_tbd(priv);
> priv->tx_busy = false;
> _eth_drv_tx_done(sc, priv->curr_tx_key, 0);
> }
>
> /* Service the RX buffers when we get something */
> if (rsr & AT91_EMAC_RSR_REC) {
>
> #define NOT_DEFINED -1
>
> cyg_int32 begpack = NOT_DEFINED;
> cyg_int32 i = 0;
>
> idx = priv->curr_rbd_idx;
> cnt = 0;
>
> for (i = 0; i < CYGNUM_DEVS_ETH_ARM_AT91_RX_BUFS; i++) {
>
> if (priv->rbd[idx].addr & AT91_EMAC_RBD_ADDR_OWNER_SW){
>
> if (priv->rbd[idx].sr & AT91_EMAC_RBD_SR_SOF){
> begpack = idx;
> }
> if (begpack != NOT_DEFINED){
> if (priv->rbd[idx].sr & AT91_EMAC_RBD_SR_LEN_MASK) {
> cnt += (priv->rbd[idx].sr & AT91_EMAC_RBD_SR_LEN_MASK);
> } else {
> cnt += AT91_EMAC_RX_BUFF_SIZE;
> }
> } else {
> priv->rbd[idx].addr &= ~(AT91_EMAC_RBD_ADDR_OWNER_SW);
> }
> if (priv->rbd[idx].sr & AT91_EMAC_RBD_SR_EOF){
> if (begpack == NOT_DEFINED){
> cnt = 0;
> priv->rbd[idx].addr &= ~(AT91_EMAC_RBD_ADDR_OWNER_SW);
> } else {
> priv->curr_rbd_idx = begpack;
> _eth_drv_recv(sc, cnt);
> }
> }
> } else {
> if (begpack != NOT_DEFINED){
> while (begpack != idx){
> priv->rbd[begpack].addr &= ~(AT91_EMAC_RBD_ADDR_OWNER_SW);
> begpack++;
> if (begpack > CYGNUM_DEVS_ETH_ARM_AT91_RX_BUFS-1) {
> begpack = 0;
> }
> }
>
> begpack = NOT_DEFINED;
> cnt = 0;
> }
888,908c919,921
< }
<
< /* Check that we did find a SOF*/
< if ((priv->rbd[priv->curr_rbd_idx].addr &
< AT91_EMAC_RBD_ADDR_OWNER_SW) &&
< (priv->rbd[priv->curr_rbd_idx].sr & AT91_EMAC_RBD_SR_SOF))
< {
< cnt = 0;
< for (ctr=0;ctr<CYGNUM_DEVS_ETH_ARM_AT91_RX_BUFS;ctr++)
< {
< idx = (ctr+priv->curr_rbd_idx)%CYGNUM_DEVS_ETH_ARM_AT91_RX_BUFS;
< cnt += (priv->rbd[idx].sr & AT91_EMAC_RBD_SR_LEN_MASK);
< if (priv->rbd[idx].sr & AT91_EMAC_RBD_SR_EOF)
< {
< /* The recv function will adjust the current buffer idx
< after the buffer has been cleared
< */
< if (cnt)
< _eth_drv_recv(sc,cnt);
< break;
< }
---
> idx++;
> if (idx > CYGNUM_DEVS_ETH_ARM_AT91_RX_BUFS-1) {
> idx = 0;
910,921c923,924
< }
< }
< }
<
< if (rsr&AT91_EMAC_RSR_BNA)
< {
< debug1_printf("AT91_ETH: Rx BNA\n");
< }
< if (rsr&AT91_EMAC_RSR_OVR)
< {
< debug1_printf("AT91_ETH: Rx OVR\n");
< }
---
> }
> }
922a926,931
> if (rsr & AT91_EMAC_RSR_BNA) {
> debug1_printf("AT91_ETH: Rx BNA\n");
> }
> if (rsr & AT91_EMAC_RSR_OVR) {
> debug1_printf("AT91_ETH: Rx OVR\n");
> }
925,943c934,935
< static void
< at91_eth_recv(struct eth_drv_sc *sc,
< struct eth_drv_sg *sg_list,
< int sg_len)
< {
< at91_eth_priv_t *priv = (at91_eth_priv_t *)sc->driver_private;
< int i;
< cyg_uint32 bytes_in_buffer;
< cyg_uint32 bytes_in_list = 0;
< cyg_uint32 bytes_needed_list = 0;
< cyg_uint32 buffer_pos = 0;
< cyg_uint8 * sg_buf;
< cyg_uint32 total_bytes = 0;
<
< for(i = 0;i<sg_len;i++)
< {
< while(bytes_in_list < sg_list[i].len)
< {
< bytes_needed_list = sg_list[i].len - bytes_in_list;
---
> static void
> at91_eth_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len) {
945,954c937,955
< if(priv->rbd[priv->curr_rbd_idx].sr & AT91_EMAC_RBD_SR_EOF)
< {
< bytes_in_buffer =
< ((priv->rbd[priv->curr_rbd_idx].sr & AT91_EMAC_RBD_SR_LEN_MASK)
< - total_bytes) - buffer_pos;
< }
< else
< {
< bytes_in_buffer = AT91_EMAC_RX_BUFF_SIZE - buffer_pos;
< }
---
> at91_eth_priv_t *priv = (at91_eth_priv_t *) sc->driver_private;
> int i;
> cyg_uint32 bytes_in_buffer = 0;
> cyg_uint32 bytes_in_list = 0;
> cyg_uint32 bytes_needed_list = 0;
> cyg_uint32 buffer_pos = 0;
> cyg_uint8 * sg_buf;
> cyg_uint32 total_bytes = 0;
>
> for (i = 0; i < sg_len; i++) {
> while (bytes_in_list < sg_list[i].len) {
> bytes_needed_list = sg_list[i].len - bytes_in_list;
>
> if (priv->rbd[priv->curr_rbd_idx].sr & AT91_EMAC_RBD_SR_LEN_MASK) {
> bytes_in_buffer = ((priv->rbd[priv->curr_rbd_idx].sr & AT91_EMAC_RBD_SR_LEN_MASK) - total_bytes)
> - buffer_pos;
> } else {
> bytes_in_buffer = AT91_EMAC_RX_BUFF_SIZE - buffer_pos;
> }
956c957
< sg_buf = (cyg_uint8 *)(sg_list[i].buf);
---
> sg_buf = (cyg_uint8 *) (sg_list[i].buf);
958,983c959,979
< if(bytes_needed_list < bytes_in_buffer)
< {
< if(sg_buf != NULL)
< memcpy(&sg_buf[bytes_in_list],
< &priv->rb[priv->curr_rbd_idx].rb[buffer_pos],
< bytes_needed_list);
< bytes_in_list += bytes_needed_list;
< buffer_pos += bytes_needed_list;
< total_bytes += bytes_needed_list;
< }
< else
< {
< if(sg_buf != NULL)
< memcpy(&sg_buf[bytes_in_list],
< &priv->rb[priv->curr_rbd_idx].rb[buffer_pos],
< bytes_in_buffer);
< bytes_in_list += bytes_in_buffer;
< total_bytes += bytes_in_buffer;
<
< /* Step our buffer on one */
< priv->rbd[priv->curr_rbd_idx].addr &=
< ~(AT91_EMAC_RBD_ADDR_OWNER_SW);
< priv->curr_rbd_idx++;
< if(priv->curr_rbd_idx >= CYGNUM_DEVS_ETH_ARM_AT91_RX_BUFS)
< {
< priv->curr_rbd_idx = 0;
---
> if (bytes_needed_list < bytes_in_buffer) {
> if (sg_buf != NULL)
> memcpy(&sg_buf[bytes_in_list], &priv->rb[priv->curr_rbd_idx].rb[buffer_pos],
> bytes_needed_list);
> bytes_in_list += bytes_needed_list;
> buffer_pos += bytes_needed_list;
> total_bytes += bytes_needed_list;
> } else {
> if (sg_buf != NULL)
> memcpy(&sg_buf[bytes_in_list], &priv->rb[priv->curr_rbd_idx].rb[buffer_pos],
> bytes_in_buffer);
> bytes_in_list += bytes_in_buffer;
> total_bytes += bytes_in_buffer;
>
> /* Step our buffer on one */
> priv->rbd[priv->curr_rbd_idx].addr &= ~(AT91_EMAC_RBD_ADDR_OWNER_SW);
> priv->curr_rbd_idx++;
> if (priv->curr_rbd_idx > CYGNUM_DEVS_ETH_ARM_AT91_RX_BUFS-1) {
> priv->curr_rbd_idx = 0;
> }
> buffer_pos = 0;
985,988c981,982
< buffer_pos = 0;
< }
< }
< }
---
> }
> }
989a984,985
>
>
diff -r /cygdrive/c/ALL/ecos20150205/ecos/packages/io/eth/current/src/lwip/eth_drv.c "/cygdrive/c/ALL/ecos20150205.olis eth flicks/ecos/packages/io/eth/current/src/lwip/eth_drv.c"
414,418c414,416
< if (p == NULL) {
< START_CONSOLE();
< diag_printf("cannot allocate pbuf to receive packet\n");
< END_CONSOLE();
< return;
---
> while (!p){
> cyg_thread_delay(10);
> p = pbuf_alloc(PBUF_RAW, total_len, PBUF_POOL);
diff -r /cygdrive/c/ALL/ecos20150205/ecos/packages/net/lwip_tcpip/current/cdl/lwip_net.cdl "/cygdrive/c/ALL/ecos20150205.olis eth flicks/ecos/packages/net/lwip_tcpip/current/cdl/lwip_net.cdl"
40c40
< # Author(s): Simon Kallweit
---
> # Author(s): Simon Kallweit
53c53
<
---
>
57c57
< core/memp.c \
---
> core/memp.c \
1394c1394
< default_value 8
---
> default_value CYGNUM_KERNEL_SYNCH_MBOX_QUEUE_SIZE
1403c1403
< default_value 16
---
> default_value CYGNUM_KERNEL_SYNCH_MBOX_QUEUE_SIZE
diff -r /cygdrive/c/ALL/ecos20150205/ecos/packages/net/lwip_tcpip/current/src/ecos/sequential.c "/cygdrive/c/ALL/ecos20150205.olis eth flicks/ecos/packages/net/lwip_tcpip/current/src/ecos/sequential.c"
272d271
< if (sc->state & ETH_DRV_NEEDS_DELIVERY) {
274c273
< cyg_bool was_ctrlc_int;
---
> cyg_bool was_ctrlc_int;
276c275
< sc->state &= ~ETH_DRV_NEEDS_DELIVERY;
---
> sc->state &= ~ETH_DRV_NEEDS_DELIVERY;
278,280c277,279
< was_ctrlc_int = HAL_CTRLC_CHECK(sc->funs->int_vector(sc),
< (int) sc);
< if (!was_ctrlc_int) // Fall through and run normal code
---
> was_ctrlc_int = HAL_CTRLC_CHECK(sc->funs->int_vector(sc),
> (int) sc);
> if (!was_ctrlc_int) // Fall through and run normal code
282,283c281
< sc->funs->deliver(sc);
< }
---
> sc->funs->deliver(sc);
diff -r /cygdrive/c/ALL/ecos20150205/ecos/packages/net/lwip_tcpip/current/src/ecos/sys_arch.c "/cygdrive/c/ALL/ecos20150205.olis eth flicks/ecos/packages/net/lwip_tcpip/current/src/ecos/sys_arch.c"
111,120c111,120
< var_data,
< sizeof(var_data),
< &var_handle,
< &var_mempool
< );
<
< threads = NULL;
< to.next = NULL;
<
< cyg_mutex_init(&stack_mutex);
---
> var_data,
> sizeof(var_data),
> &var_handle,
> &var_mempool
> );
>
> threads = NULL;
> to.next = NULL;
>
> cyg_mutex_init(&stack_mutex);
215,216c215,216
< cyg_mbox *mbox;
< cyg_handle_t handle;
---
> cyg_mbox *mbox;
> cyg_handle_t handle;
220,223c220,223
< mbox = (cyg_mbox *) cyg_mempool_var_try_alloc(var_handle, sizeof(cyg_mbox));
< if (!mbox)
< return SYS_MBOX_NULL;
< cyg_mbox_create(&handle, mbox);
---
> mbox = (cyg_mbox *) cyg_mempool_var_try_alloc(var_handle, sizeof(cyg_mbox));
> if (!mbox)
> return SYS_MBOX_NULL;
> cyg_mbox_create(&handle, mbox);
231c231
< return handle;
---
> return handle;
249,250c249,250
< cyg_mbox_delete(mbox);
< cyg_mempool_var_free(var_handle, (void *) mbox);
---
> cyg_mbox_delete(mbox);
> cyg_mempool_var_free(var_handle, (void *) mbox);
270,271c270,271
< sys_mbox_post(sys_mbox_t mbox, void *msg)
< {
---
> sys_mbox_post(sys_mbox_t mbox, void *msg){
>
273c273
< if (!msg)
---
> if (!msg){
275c275,278
< while (cyg_mbox_put(mbox, msg) == false);
---
> }
> while (!cyg_mbox_put(mbox, msg)){
> cyg_thread_yield();
> }
277d279
<
next reply other threads:[~2015-04-20 11:19 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-04-20 11:19 oliver.munz [this message]
2015-06-10 12:12 ` Lambrecht Jürgen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=a5143a33e2b4952478f8291234b9b4b1@haven.inspiration.ch \
--to=olimunz@snr.ch \
--cc=ecos-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).