Skip to content

Commit 21483cd

Browse files
authored
Merge pull request #6167 from hug-dev/cm3ds-bug-fix
CM3DS Maintenance Pull Request: Bug fixes (1/4)
2 parents 478fda7 + ef7b16d commit 21483cd

File tree

3 files changed

+77
-17
lines changed

3 files changed

+77
-17
lines changed

features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_CM3DS_MPS2/lwipopts_conf.h

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2017 ARM Limited
1+
/* Copyright (c) 2017-2018 ARM Limited
22
*
33
* Licensed under the Apache License, Version 2.0 (the "License");
44
* you may not use this file except in compliance with the License.
@@ -22,12 +22,22 @@
2222
/* size is 1522 bytes to accommodate the four-byte VLAN tag. */
2323
#define ETH_MAX_FLEN 1522u /* recommended size for a VLAN frame */
2424

25-
/* Maximum Transfer Unit
26-
* The IEEE 802.3 specification limits the data portion of the 802.3 frame
27-
* to a minimum of 46 and a maximum of 1500 bytes, this is on L3 level.
28-
*/
25+
/*
26+
* Maximum Transfer Unit
27+
* The IEEE 802.3 specification limits the data portion of the 802.3 frame
28+
* to a minimum of 46 and a maximum of 1522 bytes, this is on L2 level.
29+
*/
2930
#define ETH_L2_HEADER_LEN 22u
3031

3132
#define ETH_MAX_PAYLOAD_LEN (ETH_MAX_FLEN - ETH_L2_HEADER_LEN)
3233

34+
/*
35+
* Set this value to 2 to ensure that payload address of packet buffers is
36+
* aligned on a 32 bits boundary.
37+
* The padding is removed before passing the packet to the ethernet driver,
38+
* hence defining this value to 2 will not prevent alignment issues inside the
39+
* ethernet driver.
40+
*/
41+
#define ETH_PAD_SIZE 0
42+
3343
#endif /* LWIPOPTS_CONF_H */

features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_CM3DS_MPS2/mps2_emac.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* mbed Microcontroller Library
2-
* Copyright (c) 2017 ARM Limited
2+
* Copyright (c) 2017-2018 ARM Limited
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -316,16 +316,16 @@ err_t eth_arch_enetif_init(struct netif *netif)
316316
err_t error = ERR_OK;
317317
struct ethernetif *ethernetif;
318318

319-
ethernetif->is_enabled = 0;
320-
321319
LWIP_ASSERT("netif != NULL", (netif != NULL));
322-
323320
ethernetif = mem_malloc(sizeof(struct ethernetif));
321+
324322
if (ethernetif == NULL) {
325323
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_init: out of memory\n"));
326324
return ERR_MEM;
327325
}
328326

327+
ethernetif->is_enabled = 0;
328+
329329
#if LWIP_NETIF_HOSTNAME
330330
/* Initialize interface hostname */
331331
netif->hostname = HOSTNAME_STRING;

targets/TARGET_ARM_SSG/TARGET_CM3DS_MPS2/SDK/smsc9220_eth.c

Lines changed: 58 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* mbed Microcontroller Library
2-
* Copyright (c) 2017 ARM Limited
2+
* Copyright (c) 2017-2018 ARM Limited
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -426,6 +426,53 @@ static int smsc9220_check_id(void)
426426
return 0;
427427
}
428428

429+
/**
430+
* \brief Fill the SMSC9220 TX FIFO with a number of words at an aligned
431+
* address.
432+
*
433+
* \param[in] data Pointer to the aligned data that should be sent.
434+
* \param[in] dwords_to_write Number of data words to write.
435+
*/
436+
static void fill_tx_fifo_aligned(unsigned int *data,
437+
unsigned int dwords_to_write)
438+
{
439+
while (dwords_to_write > 0) {
440+
SMSC9220->TX_DATA_PORT = *data;
441+
data++;
442+
dwords_to_write--;
443+
}
444+
}
445+
446+
/**
447+
* \brief Fill the SMSC9220 TX FIFO with a number of words at an unaligned
448+
* address. This function ensures that loading words at that address will
449+
* not generate unaligned access which can trigger an exception to the
450+
* processor.
451+
*
452+
* \param[in] data Pointer to the unaligned data that should be sent.
453+
* \param[in] dwords_to_write Number of data words to write.
454+
*/
455+
static void fill_tx_fifo_unaligned(uint8_t *data, unsigned int dwords_to_write)
456+
{
457+
/*
458+
* Prevent unaligned word access from data pointer, 4 bytes are copied to
459+
* this variable for each word that need to be sent.
460+
*/
461+
unsigned int tx_data_port_tmp = 0;
462+
uint8_t *tx_data_port_tmp_ptr = (uint8_t *)&tx_data_port_tmp;
463+
464+
while (dwords_to_write > 0) {
465+
/* Keep the same endianness in data than in the temp variable */
466+
tx_data_port_tmp_ptr[0] = data[0];
467+
tx_data_port_tmp_ptr[1] = data[1];
468+
tx_data_port_tmp_ptr[2] = data[2];
469+
tx_data_port_tmp_ptr[3] = data[3];
470+
SMSC9220->TX_DATA_PORT = tx_data_port_tmp;
471+
data += 4;
472+
dwords_to_write--;
473+
}
474+
}
475+
429476
/*----------------------------------------------------------------------------
430477
Public API
431478
*----------------------------------------------------------------------------*/
@@ -574,7 +621,6 @@ int smsc9220_send_by_chunks(unsigned int total_packet_length, int is_new_packet,
574621
int is_last_segment = 0; /* signing this is the last segment of the packet to be sent */
575622
unsigned int txcmd_a, txcmd_b = 0;
576623
unsigned int dwords_to_write = 0;
577-
unsigned int *pktptr = 0;
578624
unsigned int xmit_inf = 0;
579625
unsigned int tx_buffer_free_space = 0;
580626
volatile unsigned int xmit_stat = 0;
@@ -602,7 +648,6 @@ int smsc9220_send_by_chunks(unsigned int total_packet_length, int is_new_packet,
602648
is_last_segment = 1;
603649
}
604650

605-
pktptr = (unsigned int *) data;
606651
txcmd_a = 0;
607652
txcmd_b = 0;
608653

@@ -616,11 +661,16 @@ int smsc9220_send_by_chunks(unsigned int total_packet_length, int is_new_packet,
616661
SMSC9220->TX_DATA_PORT = txcmd_b;
617662
dwords_to_write = (current_size + 3) >> 2;
618663

619-
/* PIO Copy to FIFO. Could replace this with DMA. */
620-
while(dwords_to_write > 0) {
621-
SMSC9220->TX_DATA_PORT = *pktptr;
622-
pktptr++;
623-
dwords_to_write--;
664+
/*
665+
* Copy to TX FIFO
666+
* The function to use depends on the alignment of the data pointer on a 32
667+
* bits boundary.
668+
*/
669+
if (((unsigned int)data % sizeof(uint32_t)) == 0) {
670+
/* Cast is safe because we know data is aligned */
671+
fill_tx_fifo_aligned((unsigned int *)data, dwords_to_write);
672+
} else {
673+
fill_tx_fifo_unaligned((uint8_t *)data, dwords_to_write);
624674
}
625675

626676
if (is_last_segment) {

0 commit comments

Comments
 (0)