You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by gn...@apache.org on 2020/06/11 23:15:09 UTC

[incubator-nuttx] branch SocketCAN updated (5f0179e -> 2df19bf)

This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a change to branch SocketCAN
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git.


 discard 5f0179e  Use LPO 32Khz clock for RTC
 discard ec7b886  Backport code style fixes
 discard 0fe722c  NET_CAN_RAW_TX_DEADLINE use relative time with watchdog Instead of a polling timer, also every mailbox get its own watchdog and gets cancelled when a tx interrupt for the corresponding mailbox occurs.
 discard 059d448  Made can/error.h nxstyle compliant
 discard f08151c  Implement NET_CAN_RAW_TX_DEADLINE in SocketCAN and S32K1XX FlexCAN driver
 discard c9844c2  Code style fixes 4
 discard b37b616  Socket: Control message addded initial stubs for sendmsg()
 discard 8a73721  Code style fixes 3
 discard 95d8441  Code style fixes 2
 discard 8058234  Code style fixes
 discard 5f13717  S32K1XX SocketCAN style fixes
 discard cd52a3f  S32K1XX Added High res timer support FlexCAN allocate memory for timestamp
 discard e017495  Added support for SO_TIMESTAMP in socketlayer and SocketCAN     Cleanup FlexCAN driver driver     Disabled workqueue based TX in FlexCAN
 discard 754b9ae  Added support for SO_TIMESTAMP in socketlayer and SocketCAN Cleanup FlexCAN driver driver Disabled workqueue based TX in FlexCAN
 discard 785ef9d  Added devif_cansend.c (forgotten in commit e485581)
 discard d6502bc  SocketCAN added protocol 0 to suport netlib_ifup with NET_PKT disabled
 discard 1f32cf3  Added functional support for CAN_RAW_FILTER sockopt
 discard 8d24e58  SocketCAN recfrom added non-blocking behavior support FlexCAN support sending extended CAN id
 discard 8bc2922  SocketCAN removed NET_TCP and NET_PKT dependencies
 discard e67d2cb  Fixed SocketCAN IOB default config and IOB typos
 discard 1fa53ed  Added CAN_RAW_FD_FRAMES sockopt support
 discard 6d8e06b  FlexCAN transmit CAN FD support
 discard 437ca3a  Added CAN FD driver support
 discard a848408  PR350 Coding Standard Corrections
 discard b76d609  Added basic poll()/select support
 discard 72d1045  SocketCAN initial receive working as well
 discard 5076da1  Added GPIO code to test SocketCAN performance
 discard d600a3d  PoC S32K1XX FlexCAN sends CAN msgs through SocketCAN
 discard 46c67a4  net/:  Add WIP initial framework for SocketCAN sockets.
 discard 9ec0f58  include/netpacket/can.h:  Add CAN socket family definitions
 discard 53fe91c  include/sys/socket.h:  Add CAN socket family.
     add 4fe35cc  boards: Remove OUTPUT_FORMAT and OUTPUT_ARCH from ld script
     add 57caa4e  libc: Move MB_LEN_MAX from lib_wctob.c to limits.h
     add f1433ee  libc: Fix the typo error in wcrtomb
     add 7cbcbcd  libc: Implement wcsrtombs, wcsnrtombs and mbsnrtowcs
     add de50900  libc: Implement mblen, mbstowcs and wcstombs
     add a7174ce  libc: Unify the selection of inline or macro
     add 9ff3242  libc: Implement tmpfile() function
     add 6b3ac93  libc: Fix a typo error in tmpfile
     add 0da3400  ez80:  Fix ez80 build problems.
     add 698ac72  stm32h7:stm32_sdmmc fix compiler error when SDMMC2 is enabled
     add 1688440  mkdeps: Quote CFLAGS to be safe with the shell
     add 44585ee  mkdeps: Use %zu/%zd printf format instead of casts
     add d05cca0  boards/mips: restore OUTPUT_FORMAT and OUTPUT_ARCH for mips link scripts
     add a55f8d2  libc: Implement vscanf() function
     add 29f9d97  libc: Call vdprintf in printf/vprintf for CONFIG_NFILE_STREAMS == 0
     add 4029706  libc: tmpfile shouldn't hardcode the folder to /tmp
     add c76443f  libc: Remove CONFIG_LIBC_TMPDIR definition from lib_mkstemp.c
     add 3c4fec8  libc: Fix warning: implicit declaration of function ‘strnlen’
     add 91779e9  arch/arm/src/stm32h7/hardware/stm32h7x3xx_spi.h: Fix nxstyle issues
     add fe44ce0  arch/arm/src/stm32h7/stm32_spi.c: Corrections for SPI master driver
     add 4935ab5  printf() and vprintf() must use C buffered I/O if available.
     add 7575518  boards/Board.mk: Remove include $(TOPDIR)/Make.defs
     add ff9d435  include/cxx/cwchar: include wctype.h to fix libcxx build break
     add ac84a51  libc/time: call _NX_OPEN/_NX_CLOSE instead of open/close
     add c45289e  Fix typo in arch/arm/src/lpc17xx_40xx/Kconfig
     add 85b859f  arch: _exit should't call nxsched_resume_scheduler twice in SMP mode
     add b4bd942  arch: Rename _exit to up_exit to follow the naming convention
     add a696788  sched: Change the return type of nxtask_activate to void
     add ef30832  include: audio: Remove CONFIG_AUDIO_DRIVER_SPECIFIC_BUFFERS from audio.h
     add 4b9886f  drivers: audio: Return -ENOTTY in xxx_ioctl() if not handled
     add 1c17e5f  arch/arm/src/stm32/Kconfig: Fix a trivial typo (I2C -> I2S)
     add a098e03  arch/arm/src/stm32/stm32_i2s.h: file hardware/stm32_i2s.h does not exist.
     add a30b77c  arch/arm/src/stm32/stm32.h: Include stm32_i2s.h
     add 1ca5527  arch/arm/src/stm32/stm32_i2s: Change the initialize function from stm32_i2sdev_initialize to stm32_i2sbus_initiliaze, to be consistent with the way other buses are initialized. The stm32_i2sdev_initiliaze (similar to stm32_spidev_initialize for example) is a board specific function that does any necessary initialization that's board depedent.
     add 871d5c6  Fix PR 1188 nxstyle issues
     add b7ab9aa  nuttx compiler.h: Add location directive for code and data
     add 36ae29c  sim: Fix hostfs errno
     add 368fbd0  cxd56: Fix lock issue in Spresense audio driver
     add 3409c98  sched/task: Simplify atexit and onexit implementation
     add 09f64dd  sched/task: Avoid the cast in atexit when CONFIG_SCHED_ONEXIT is defined
     add d065bbe  audio/pcm_decode.c: Fix #endif position when excluding stop and pause/resume.
     add 8da4b02  drivers/audio: Add CS4344 driver.
     add d001c82  boards/arm/stm32/olimex-stm32-p407: Add support for the CS4344 audio driver.
     add 36f54e2  Fix PR1201 nxstyle issues.
     add ddf2704  stm32h7:Kconfig limit STM32H7_SPIn_COMMTYPE range to valid values
     add b191714  stm32h7 boards:Emit the the D3 power domain section for locating BDMA data
     add a254023  stm32h7:SPI Locate SPI6 DMA buffers in sram4
     add a7a2726  Char drivers should return -ENOTTY if CMD is not recognized
     add a793369  stm32h7:DMA Add BDMA support
     add 465a13c  arch/arm/src: Return ENOTTY when the ioctl command is not recognized.
     add a90f657  arch/arm/src/stm32/stm32_hrtim.c: Fix nxstyle issues.
     add 4037669  boards/sim: Break out the thread loop instead calling pthread_exit
     add 9718611  Fix lpc17_40_ubxmdm.c board driver to return -ENOTTY
     add 0020091  Run nxstyle on lpc17_40_ubxmdm.c
     add d41a2f8  Add support to STM32F411CE
     add 1e8cd3f  Add initial support to STM32F411-Minimum board (aka BlackPill)
     add f227b65  Fix nxstyle issues
     add a673086  Add Apache license to Make.defs as well
     add 4fce224  Add LED support to stm32f411-minimum board
     add 73fc437  Fix nxstyle errors
     add 1b47aa1  drivers/button: Let board_button_initialize return the button number
     add a61b8a1  Fix nxstyle issue
     add 1ba1c34  drivers/led: Decopule USERLED from ARCH_HAVE_LEDS
     add 7696547  drivers/led: Let board_userled_initialize return the led number
     add 7a18ebe  drivers/led: Extend userled_set_t from 8bits to 32bits
     add 24262a4  Fix nxstyle issue
     add bcd7ccc  arch/risc-v/src/k210: Add basic gpiohs support
     add 2b0324c  boards/risc-v/k210/maix-bit: Add initial autoled support
     add d0158fe  boards: Fix Kconfig for maix-bit with QEMU
     add 6f3cef8  libc: Add the remaining wscanf series declaration
     add f4a9c45  Move Serial Console to USART1 to keep compatibility with BluePill
     add 2af72cc  eagle100: add the missing NXFLAT macros
     add e661ac5  eagle100: disable CONFIG_BOARD_LATE_INITIALIZE since board_late_initialize not defined
     add 8708e34  arch/arm/src/nrf52/nrf52_idle.c: disable WFI in up_idle
     add 7e3c341  stm32h7:Fix compiler error stm32_bdma_capable
     add 7758eb8  arch: Define INTx_C and UINTx_C macro
     add 4fbbd2e  arch: Move PRIxMAX and SCNxMAX definition to include/stdint.h
     add 43d7c1e  libc: Add IPTR for puts/fputs
     add 0317eae  libc: support CONFIG_ARCH_ROMGETC for scanf function series
     add 8a60cc0  drivers: audio: Send stop message when received the final buffer
     add 958ddc1  drivers: audio: Add a buffering feature to cxd56
     add 8ae0a13  boards: spresense: Change audio buffer size and mq size for wifi
     add 0430c6c  Add problem matching for gcc and nxstyle to github actions
     add 48dffbb  boards: spresense: Add nxrecorder to wifi/defconfig
     add 72ff383  boards/arm/stm32/stm3210e-eval/include/board.h: Fix buttons bits when CONFIG_DJOYSTICK is enabled.
     add fe7dfec  include/nuttx/input/djoystick.h: Fix some trivial typos and nxstyle issues.
     add c3ba603  boards/arm/stm32/olimex-stm32-p407: Add joystick support.
     add 6c68c2b  boards/arm/stm32/stm3210e-eval/include/board.h: Fix nxstyle issues.
     new a371873  include/sys/socket.h:  Add CAN socket family.
     new 5fa6d20  include/netpacket/can.h:  Add CAN socket family definitions
     new c09248e  net/:  Add WIP initial framework for SocketCAN sockets.
     new ff4116d  PoC S32K1XX FlexCAN sends CAN msgs through SocketCAN
     new 99952a3  Added GPIO code to test SocketCAN performance
     new d7db889  SocketCAN initial receive working as well
     new 24d8699  Added basic poll()/select support
     new 5909e58  PR350 Coding Standard Corrections
     new 58d057c  Added CAN FD driver support
     new 4a3ec73  FlexCAN transmit CAN FD support
     new 88d67a9  Added CAN_RAW_FD_FRAMES sockopt support
     new cd17447  Fixed SocketCAN IOB default config and IOB typos
     new 37bc441  SocketCAN removed NET_TCP and NET_PKT dependencies
     new cb0027f  SocketCAN recfrom added non-blocking behavior support FlexCAN support sending extended CAN id
     new c83f005  Added functional support for CAN_RAW_FILTER sockopt
     new 932daac  SocketCAN added protocol 0 to suport netlib_ifup with NET_PKT disabled
     new c040a09  Added devif_cansend.c (forgotten in commit e485581)
     new 9a537b0  Added support for SO_TIMESTAMP in socketlayer and SocketCAN Cleanup FlexCAN driver driver Disabled workqueue based TX in FlexCAN
     new 4bfb16f  Added support for SO_TIMESTAMP in socketlayer and SocketCAN     Cleanup FlexCAN driver driver     Disabled workqueue based TX in FlexCAN
     new 962049c  S32K1XX Added High res timer support FlexCAN allocate memory for timestamp
     new 7d725c1  S32K1XX SocketCAN style fixes
     new 8b9e331  Code style fixes
     new a30faa1  Code style fixes 2
     new 6dc8e9d  Code style fixes 3
     new c3cdcbf  Socket: Control message addded initial stubs for sendmsg()
     new 437d3d4  Code style fixes 4
     new e09f9e9  Implement NET_CAN_RAW_TX_DEADLINE in SocketCAN and S32K1XX FlexCAN driver
     new 7da69d5  Made can/error.h nxstyle compliant
     new 50643e3  NET_CAN_RAW_TX_DEADLINE use relative time with watchdog Instead of a polling timer, also every mailbox get its own watchdog and gets cancelled when a tx interrupt for the corresponding mailbox occurs.
     new b3ba45b  Backport code style fixes
     new 2df19bf  Use LPO 32Khz clock for RTC

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (5f0179e)
            \
             N -- N -- N   refs/heads/SocketCAN (2df19bf)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

The 31 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .github/gcc.json                                   |  28 +
 .github/nxstyle.json                               |  28 +
 .github/workflows/build.yml                        |   2 +
 .github/workflows/check.yml                        |   1 +
 Documentation/NuttxPortingGuide.html               |   6 +-
 arch/arm/include/inttypes.h                        |  21 +-
 arch/arm/include/stm32/chip.h                      |  25 +
 arch/arm/src/common/arm_exit.c                     |  12 +-
 arch/arm/src/cxd56xx/cxd56_adc.c                   |   2 +-
 arch/arm/src/lpc17xx_40xx/Kconfig                  |   2 +-
 arch/arm/src/nrf52/nrf52_idle.c                    |   8 +-
 arch/arm/src/stm32/Kconfig                         |   7 +-
 arch/arm/src/stm32/stm32.h                         |   5 +-
 arch/arm/src/stm32/stm32_hrtim.c                   | 468 ++++++++----
 arch/arm/src/stm32/stm32_i2s.c                     |   6 +-
 arch/arm/src/stm32/stm32_i2s.h                     |   5 +-
 arch/arm/src/stm32h7/Kconfig                       |   6 +
 arch/arm/src/stm32h7/hardware/stm32_bdma.h         |  40 +-
 arch/arm/src/stm32h7/hardware/stm32_dma.h          |  18 +-
 arch/arm/src/stm32h7/hardware/stm32h7x3xx_spi.h    |  41 +-
 arch/arm/src/stm32h7/stm32_dma.c                   | 235 +++++-
 arch/arm/src/stm32h7/stm32_sdmmc.c                 |   5 +
 arch/arm/src/stm32h7/stm32_spi.c                   | 156 ++--
 arch/avr/include/avr/inttypes.h                    |  21 +-
 arch/avr/include/avr32/inttypes.h                  |  21 +-
 arch/avr/src/common/up_exit.c                      |  12 +-
 arch/hc/include/inttypes.h                         |  42 +-
 arch/hc/src/common/up_exit.c                       |  12 +-
 arch/mips/include/inttypes.h                       |  21 +-
 arch/mips/src/common/mips_exit.c                   |  12 +-
 arch/misoc/include/inttypes.h                      |  21 +-
 arch/misoc/src/lm32/lm32_exit.c                    |  12 +-
 arch/misoc/src/minerva/minerva_exit.c              |  12 +-
 arch/or1k/include/inttypes.h                       |  21 +-
 arch/or1k/src/common/up_exit.c                     |  12 +-
 arch/renesas/include/m16c/inttypes.h               |  21 +-
 arch/renesas/include/rx65n/inttypes.h              |  21 +-
 arch/renesas/include/sh1/inttypes.h                |  21 +-
 arch/renesas/src/common/up_exit.c                  |  12 +-
 arch/risc-v/include/inttypes.h                     |  21 +-
 arch/risc-v/src/common/riscv_exit.c                |  12 +-
 arch/risc-v/src/k210/Make.defs                     |   5 +-
 arch/risc-v/src/k210/hardware/k210_memorymap.h     |   3 +-
 .../{hardware/k210_memorymap.h => k210_fpioa.c}    |  39 +-
 arch/risc-v/src/k210/k210_fpioa.h                  |  92 +++
 .../risc-v/src/k210/k210_gpiohs.c                  |  79 +-
 .../risc-v/src/k210/k210_gpiohs.h                  |  91 ++-
 arch/sim/include/inttypes.h                        |  34 +-
 arch/sim/src/sim/up_exit.c                         |  12 +-
 arch/sim/src/sim/up_hostfs.c                       | 100 ++-
 arch/x86/include/i486/inttypes.h                   |  21 +-
 arch/x86/src/common/up_exit.c                      |  12 +-
 arch/x86_64/include/intel64/inttypes.h             |  21 +-
 arch/x86_64/src/common/up_exit.c                   |  11 +-
 arch/xtensa/include/inttypes.h                     |  21 +-
 arch/xtensa/src/common/xtensa_exit.c               |  12 +-
 arch/z16/include/inttypes.h                        |  19 +-
 arch/z16/src/common/z16_exit.c                     |  12 +-
 arch/z80/include/ez80/inttypes.h                   |  37 +-
 arch/z80/include/z180/inttypes.h                   |  19 +-
 arch/z80/include/z8/inttypes.h                     |  19 +-
 arch/z80/include/z80/inttypes.h                    |  19 +-
 arch/z80/src/Makefile                              |   1 -
 arch/z80/src/common/z80_exit.c                     |  12 +-
 arch/z80/src/ez80/Toolchain.defs                   |   2 +-
 audio/pcm_decode.c                                 |   4 +-
 binfmt/binfmt_execmodule.c                         |  11 +-
 boards/Board.mk                                    |   2 -
 boards/Kconfig                                     |  14 +
 boards/arm/a1x/pcduino-a10/scripts/sdram.ld        |   2 -
 boards/arm/a1x/pcduino-a10/src/a1x_buttons.c       |   2 +-
 boards/arm/a1x/pcduino-a10/src/a1x_leds.c          |  12 +-
 .../arm/am335x/beaglebone-black/scripts/sdram.ld   |   2 -
 .../am335x/beaglebone-black/src/am335x_buttons.c   |   2 +-
 .../arm/am335x/beaglebone-black/src/am335x_leds.c  |   6 +-
 .../arm/cxd56xx/spresense/configs/wifi/defconfig   |   3 +-
 boards/arm/cxd56xx/spresense/src/cxd56_buttons.c   |   3 +-
 boards/arm/cxd56xx/spresense/src/cxd56_userleds.c  |   5 +-
 .../arm/efm32/efm32-g8xx-stk/src/efm32_userleds.c  |   5 +-
 .../arm/efm32/efm32gg-stk3700/src/efm32_userleds.c |   6 +-
 .../olimex-efm32g880f128-stk/src/efm32_buttons.c   |   5 +-
 boards/arm/imx6/sabre-6quad/scripts/dramboot.ld    |   2 -
 boards/arm/imx6/sabre-6quad/src/imx_userleds.c     |   5 +-
 boards/arm/imxrt/imxrt1020-evk/src/imxrt_buttons.c |   3 +-
 .../arm/imxrt/imxrt1020-evk/src/imxrt_userleds.c   |   5 +-
 boards/arm/imxrt/imxrt1050-evk/src/imxrt_buttons.c |   3 +-
 .../arm/imxrt/imxrt1050-evk/src/imxrt_userleds.c   |   5 +-
 boards/arm/imxrt/imxrt1060-evk/src/imxrt_buttons.c |   3 +-
 .../arm/imxrt/imxrt1060-evk/src/imxrt_userleds.c   |   5 +-
 boards/arm/kinetis/freedom-k28f/src/k28_userleds.c |   5 +-
 boards/arm/kinetis/freedom-k64f/src/k64_buttons.c  |  11 +-
 boards/arm/kinetis/freedom-k64f/src/k64_userleds.c |   5 +-
 boards/arm/kinetis/freedom-k66f/src/k66_buttons.c  |  11 +-
 boards/arm/kinetis/freedom-k66f/src/k66_userleds.c |   5 +-
 boards/arm/kinetis/kwikstik-k40/src/k40_buttons.c  |  12 +-
 boards/arm/kinetis/teensy-3.x/src/k20_userleds.c   |   5 +-
 boards/arm/kinetis/twr-k60n512/src/k60_buttons.c   |   4 +-
 boards/arm/lpc17xx_40xx/lincoln60/include/board.h  |  21 +-
 .../lpc17xx_40xx/lincoln60/src/lpc17_40_buttons.c  |   9 +-
 .../lpc4088-devkit/src/lpc17_40_buttons.c          |   8 +-
 .../lpc4088-devkit/src/lpc17_40_userleds.c         |   5 +-
 .../lpc4088-quickstart/src/lpc17_40_buttons.c      |   4 +-
 .../lpc4088-quickstart/src/lpc17_40_userleds.c     |   5 +-
 .../lpc17xx_40xx/lx_cpu/src/lpc17_40_userleds.c    |   5 +-
 .../olimex-lpc1766stk/src/lpc17_40_buttons.c       |  13 +-
 .../olimex-lpc1766stk/src/lpc17_40_leds.c          |   7 +-
 .../lpc17xx_40xx/open1788/src/lpc17_40_buttons.c   |  16 +-
 .../lpc17xx_40xx/open1788/src/lpc17_40_userleds.c  |   5 +-
 boards/arm/lpc17xx_40xx/pnev5180b/include/board.h  |  46 +-
 .../lpc17xx_40xx/u-blox-c027/src/lpc17_40_ubxmdm.c | 232 ++++--
 .../zkit-arm-1769/src/lpc17_40_buttons.c           |   5 +-
 boards/arm/lpc31xx/ea3131/src/lpc31_buttons.c      |   3 +-
 boards/arm/lpc31xx/ea3152/src/lpc31_buttons.c      |   3 +-
 .../arm/lpc31xx/olimex-lpc-h3131/src/lpc31_leds.c  |   6 +-
 boards/arm/lpc43xx/bambino-200e/include/board.h    |  28 +-
 .../arm/lpc43xx/bambino-200e/src/lpc43_autoleds.c  |   6 +-
 .../arm/lpc43xx/bambino-200e/src/lpc43_buttons.c   |   6 +-
 .../arm/lpc43xx/bambino-200e/src/lpc43_userleds.c  |   7 +-
 boards/arm/lpc43xx/lpc4330-xplorer/include/board.h |  26 +-
 .../lpc43xx/lpc4330-xplorer/src/lpc43_autoleds.c   |   4 +-
 .../lpc43xx/lpc4330-xplorer/src/lpc43_buttons.c    |   8 +-
 .../lpc43xx/lpc4330-xplorer/src/lpc43_userleds.c   |   5 +-
 boards/arm/lpc43xx/lpc4337-ws/README.txt           |   4 +-
 boards/arm/lpc43xx/lpc4337-ws/include/board.h      |  15 +-
 boards/arm/lpc43xx/lpc4357-evb/README.txt          |   4 +-
 boards/arm/lpc43xx/lpc4357-evb/include/board.h     |  21 +-
 boards/arm/lpc43xx/lpc4357-evb/src/lpc43_buttons.c |   9 +-
 .../arm/lpc43xx/lpc4357-evb/src/lpc43_userleds.c   |   9 +-
 boards/arm/lpc43xx/lpc4370-link2/README.txt        |   4 +-
 boards/arm/lpc43xx/lpc4370-link2/include/board.h   |  15 +-
 .../arm/lpc43xx/lpc4370-link2/src/lpc43_userleds.c |   5 +-
 .../lpc54xx/lpcxpresso-lpc54628/include/board.h    |   9 +-
 .../lpcxpresso-lpc54628/src/lpc54_buttons.c        |   4 +-
 .../lpcxpresso-lpc54628/src/lpc54_userleds.c       |   5 +-
 .../max326xx/max32660-evsys/src/max326_button.c    |   3 +-
 .../max326xx/max32660-evsys/src/max326_userleds.c  |   5 +-
 boards/arm/nrf52/nrf52-feather/README.txt          |   4 +-
 boards/arm/nrf52/nrf52-feather/include/board.h     |   8 +-
 .../arm/nrf52/nrf52-feather/src/nrf52_userleds.c   |   9 +-
 boards/arm/nrf52/nrf52832-dk/README.txt            |   4 +-
 boards/arm/nrf52/nrf52832-dk/include/board.h       |   8 +-
 boards/arm/nrf52/nrf52832-dk/src/nrf52_buttons.c   |   4 +-
 boards/arm/nrf52/nrf52832-dk/src/nrf52_userleds.c  |   9 +-
 boards/arm/nrf52/nrf52840-dk/include/board.h       |   8 +-
 boards/arm/nrf52/nrf52840-dk/src/nrf52_buttons.c   |   4 +-
 boards/arm/nrf52/nrf52840-dk/src/nrf52_userleds.c  |   9 +-
 boards/arm/nrf52/nrf52840-dongle/include/board.h   |   8 +-
 .../arm/nrf52/nrf52840-dongle/src/nrf52_userleds.c |   9 +-
 .../rddrone-uavcan144/src/s32k1xx_buttons.c        |   3 +-
 .../rddrone-uavcan144/src/s32k1xx_userleds.c       |   5 +-
 .../rddrone-uavcan146/src/s32k1xx_buttons.c        |   3 +-
 .../rddrone-uavcan146/src/s32k1xx_userleds.c       |   5 +-
 .../arm/s32k1xx/s32k118evb/src/s32k1xx_buttons.c   |   3 +-
 .../arm/s32k1xx/s32k118evb/src/s32k1xx_userleds.c  |   5 +-
 .../arm/s32k1xx/s32k144evb/src/s32k1xx_buttons.c   |   3 +-
 .../arm/s32k1xx/s32k144evb/src/s32k1xx_userleds.c  |   5 +-
 .../arm/s32k1xx/s32k146evb/src/s32k1xx_buttons.c   |   3 +-
 .../arm/s32k1xx/s32k146evb/src/s32k1xx_userleds.c  |   5 +-
 .../arm/s32k1xx/s32k148evb/src/s32k1xx_buttons.c   |   3 +-
 .../arm/s32k1xx/s32k148evb/src/s32k1xx_userleds.c  |   5 +-
 boards/arm/sam34/arduino-due/src/sam_userleds.c    |   5 +-
 .../arm/sam34/flipnclick-sam3x/src/sam_userleds.c  |   5 +-
 boards/arm/sam34/sam3u-ek/src/sam_buttons.c        |  11 +-
 boards/arm/sam34/sam4e-ek/src/sam_buttons.c        |  11 +-
 boards/arm/sam34/sam4l-xplained/src/sam_buttons.c  |   3 +-
 boards/arm/sam34/sam4l-xplained/src/sam_userleds.c |  10 +-
 .../arm/sam34/sam4s-xplained-pro/src/sam_buttons.c |   3 +-
 .../sam34/sam4s-xplained-pro/src/sam_userleds.c    |   8 +-
 boards/arm/sam34/sam4s-xplained/src/sam_buttons.c  |   3 +-
 boards/arm/sam34/sam4s-xplained/src/sam_userleds.c |   5 +-
 boards/arm/sama5/sama5d2-xult/scripts/dramboot.ld  |   2 -
 boards/arm/sama5/sama5d2-xult/scripts/isram.ld     |   2 -
 boards/arm/sama5/sama5d2-xult/scripts/uboot.ld     |   2 -
 boards/arm/sama5/sama5d2-xult/src/sam_buttons.c    |   3 +-
 boards/arm/sama5/sama5d2-xult/src/sam_userleds.c   |   5 +-
 boards/arm/sama5/sama5d3-xplained/scripts/ddram.ld |   2 -
 boards/arm/sama5/sama5d3-xplained/scripts/isram.ld |   2 -
 .../arm/sama5/sama5d3-xplained/src/sam_buttons.c   |   3 +-
 .../arm/sama5/sama5d3-xplained/src/sam_userleds.c  |   6 +-
 boards/arm/sama5/sama5d3x-ek/scripts/ddram.ld      |   2 -
 boards/arm/sama5/sama5d3x-ek/scripts/isram.ld      |   2 -
 boards/arm/sama5/sama5d3x-ek/scripts/nor-ddram.ld  |   2 -
 boards/arm/sama5/sama5d3x-ek/scripts/nor-isram.ld  |   2 -
 boards/arm/sama5/sama5d3x-ek/scripts/pg-sram.ld    |   2 -
 boards/arm/sama5/sama5d3x-ek/src/sam_buttons.c     |   4 +-
 boards/arm/sama5/sama5d3x-ek/src/sam_userleds.c    |   6 +-
 boards/arm/sama5/sama5d4-ek/scripts/dramboot.ld    |   2 -
 boards/arm/sama5/sama5d4-ek/scripts/isram.ld       |   2 -
 boards/arm/sama5/sama5d4-ek/scripts/uboot.ld       |   2 -
 boards/arm/sama5/sama5d4-ek/src/sam_buttons.c      |   4 +-
 boards/arm/sama5/sama5d4-ek/src/sam_userleds.c     |  19 +-
 boards/arm/samd2l2/arduino-m0/src/sam_userleds.c   |  11 +-
 .../arm/samd2l2/samd20-xplained/src/sam_buttons.c  |   7 +-
 .../arm/samd2l2/samd20-xplained/src/sam_userleds.c |   9 +-
 .../arm/samd2l2/samd21-xplained/src/sam_buttons.c  |   7 +-
 .../arm/samd2l2/samd21-xplained/src/sam_userleds.c |  15 +-
 .../arm/samd2l2/saml21-xplained/src/sam_buttons.c  |   3 +-
 .../arm/samd2l2/saml21-xplained/src/sam_userleds.c |  12 +-
 boards/arm/samd5e5/metro-m4/src/sam_userleds.c     |   5 +-
 .../samd5e5/same54-xplained-pro/src/sam_userleds.c |  10 +-
 boards/arm/samv7/same70-xplained/src/sam_buttons.c |   7 +-
 .../arm/samv7/same70-xplained/src/sam_userleds.c   |   5 +-
 boards/arm/samv7/samv71-xult/src/sam_buttons.c     |  11 +-
 boards/arm/samv7/samv71-xult/src/sam_userleds.c    |   5 +-
 boards/arm/stm32/axoloti/src/stm32_buttons.c       |   4 +-
 boards/arm/stm32/axoloti/src/stm32_userleds.c      |   5 +-
 .../arm/stm32/b-g474e-dpow1/src/stm32_userleds.c   |   5 +-
 .../arm/stm32/clicker2-stm32/src/stm32_buttons.c   |  35 +-
 .../arm/stm32/clicker2-stm32/src/stm32_userleds.c  |   9 +-
 boards/arm/stm32/cloudctrl/src/stm32_buttons.c     |  53 +-
 boards/arm/stm32/cloudctrl/src/stm32_userleds.c    |  16 +-
 boards/arm/stm32/fire-stm32v2/src/stm32_buttons.c  |  23 +-
 boards/arm/stm32/fire-stm32v2/src/stm32_userleds.c |  14 +-
 boards/arm/stm32/hymini-stm32v/src/stm32_buttons.c |  32 +-
 boards/arm/stm32/nucleo-f103rb/src/stm32_buttons.c |   3 +-
 .../arm/stm32/nucleo-f103rb/src/stm32_userleds.c   |   5 +-
 boards/arm/stm32/nucleo-f207zg/src/stm32_buttons.c |   6 +-
 .../arm/stm32/nucleo-f207zg/src/stm32_userleds.c   |  10 +-
 boards/arm/stm32/nucleo-f302r8/src/stm32_buttons.c |   3 +-
 .../arm/stm32/nucleo-f302r8/src/stm32_userleds.c   |   5 +-
 boards/arm/stm32/nucleo-f303re/src/stm32_buttons.c |   3 +-
 .../arm/stm32/nucleo-f303re/src/stm32_userleds.c   |   5 +-
 boards/arm/stm32/nucleo-f303ze/src/stm32_buttons.c |   6 +-
 .../arm/stm32/nucleo-f303ze/src/stm32_userleds.c   |  10 +-
 boards/arm/stm32/nucleo-f410rb/src/stm32_buttons.c |  30 +-
 .../arm/stm32/nucleo-f410rb/src/stm32_userleds.c   |  10 +-
 boards/arm/stm32/nucleo-f429zi/src/stm32_buttons.c |   3 +-
 .../arm/stm32/nucleo-f429zi/src/stm32_userleds.c   |   6 +-
 boards/arm/stm32/nucleo-f446re/src/stm32_buttons.c |   7 +-
 .../arm/stm32/nucleo-f446re/src/stm32_userleds.c   |  10 +-
 boards/arm/stm32/nucleo-f4x1re/src/stm32_buttons.c |  30 +-
 .../arm/stm32/nucleo-f4x1re/src/stm32_userleds.c   |  10 +-
 boards/arm/stm32/nucleo-l152re/src/stm32_buttons.c |   3 +-
 .../arm/stm32/nucleo-l152re/src/stm32_userleds.c   |   5 +-
 .../stm32/olimex-stm32-e407/src/stm32_buttons.c    |   8 +-
 .../stm32/olimex-stm32-e407/src/stm32_userleds.c   |  10 +-
 .../stm32/olimex-stm32-h405/src/stm32_buttons.c    |  43 +-
 .../stm32/olimex-stm32-h405/src/stm32_userleds.c   |  10 +-
 .../stm32/olimex-stm32-h407/src/stm32_buttons.c    |  12 +-
 .../stm32/olimex-stm32-h407/src/stm32_userleds.c   |  10 +-
 .../stm32/olimex-stm32-p207/src/stm32_buttons.c    |  43 +-
 .../stm32/olimex-stm32-p207/src/stm32_userleds.c   |  16 +-
 .../olimex-stm32-p407/configs/audio/defconfig      |  78 ++
 boards/arm/stm32/olimex-stm32-p407/include/board.h |  60 +-
 boards/arm/stm32/olimex-stm32-p407/src/Make.defs   |   8 +
 .../olimex-stm32-p407/src/olimex-stm32-p407.h      |  69 +-
 .../stm32/olimex-stm32-p407/src/stm32_bringup.c    |  18 +
 .../stm32/olimex-stm32-p407/src/stm32_buttons.c    |  83 +-
 .../arm/stm32/olimex-stm32-p407/src/stm32_cs4344.c | 170 +++++
 .../stm32/olimex-stm32-p407/src/stm32_djoystick.c  | 296 ++++++++
 .../stm32/olimex-stm32-p407/src/stm32_userleds.c   |  16 +-
 .../stm32/olimexino-stm32/src/olimexino-stm32.h    |  56 +-
 .../arm/stm32/olimexino-stm32/src/stm32_buttons.c  |  15 +-
 boards/arm/stm32/olimexino-stm32/src/stm32_leds.c  |   7 +-
 boards/arm/stm32/omnibusf4/src/stm32_userleds.c    |  11 +-
 boards/arm/stm32/photon/src/stm32_buttons.c        |   3 +-
 boards/arm/stm32/photon/src/stm32_userleds.c       |   5 +-
 boards/arm/stm32/shenzhou/src/stm32_buttons.c      |  74 +-
 boards/arm/stm32/shenzhou/src/stm32_userleds.c     |   6 +-
 boards/arm/stm32/stm3210e-eval/include/board.h     |  38 +-
 boards/arm/stm32/stm3210e-eval/src/stm32_buttons.c |  78 +-
 boards/arm/stm32/stm3220g-eval/src/stm32_buttons.c |  71 +-
 .../arm/stm32/stm3220g-eval/src/stm32_userleds.c   |   6 +-
 boards/arm/stm32/stm3240g-eval/src/stm32_buttons.c |  71 +-
 .../arm/stm32/stm3240g-eval/src/stm32_userleds.c   |   6 +-
 .../arm/stm32/stm32butterfly2/src/stm32_buttons.c  |  20 +-
 boards/arm/stm32/stm32butterfly2/src/stm32_leds.c  |  42 +-
 .../stm32/stm32f103-minimum/src/stm32_buttons.c    |  19 +-
 .../stm32/stm32f103-minimum/src/stm32_userleds.c   |   7 +-
 .../arm/stm32/stm32f3discovery/src/stm32_buttons.c |  58 +-
 .../stm32/stm32f3discovery/src/stm32_userleds.c    |   7 +-
 boards/arm/stm32/stm32f411-minimum/Kconfig         |  18 +
 boards/arm/stm32/stm32f411-minimum/README.txt      |   1 +
 .../stm32/stm32f411-minimum/configs/nsh/defconfig  |  55 ++
 boards/arm/stm32/stm32f411-minimum/include/board.h | 331 ++++++++
 .../stm32f411-minimum}/scripts/Make.defs           |  55 +-
 .../stm32/stm32f411-minimum/scripts/stm32f411ce.ld | 107 +++
 .../arm/stm32/stm32f411-minimum/src}/Make.defs     |  30 +-
 .../stm32/stm32f411-minimum/src/stm32_appinit.c    |  70 +-
 .../stm32f411-minimum/src/stm32_autoleds.c}        |  85 ++-
 .../arm/stm32/stm32f411-minimum/src/stm32_boot.c   |  99 +++
 .../stm32/stm32f411-minimum/src/stm32_bringup.c    |  68 +-
 boards/arm/stm32/stm32f411-minimum/src/stm32_usb.c | 340 +++++++++
 .../stm32f411-minimum/src/stm32f411-minimum.h      | 170 +++++
 .../arm/stm32/stm32f429i-disco/src/stm32_buttons.c |  61 +-
 .../stm32/stm32f429i-disco/src/stm32_userleds.c    |  20 +-
 .../arm/stm32/stm32f4discovery/src/stm32_buttons.c |  61 +-
 .../arm/stm32/stm32f4discovery/src/stm32_cs43l22.c |  39 +-
 .../stm32/stm32f4discovery/src/stm32_userleds.c    |  22 +-
 .../stm32/stm32f4discovery/src/stm32f4discovery.h  |   2 +-
 .../arm/stm32/stm32ldiscovery/src/stm32_buttons.c  |  58 +-
 .../arm/stm32/stm32ldiscovery/src/stm32_userleds.c |   5 +-
 .../arm/stm32/stm32vldiscovery/src/stm32_buttons.c |  41 +-
 .../stm32/viewtool-stm32f107/src/stm32_buttons.c   |  46 +-
 .../arm/stm32/viewtool-stm32f107/src/stm32_leds.c  |  24 +-
 .../stm32f0l0g0/nucleo-f072rb/src/stm32_buttons.c  |  30 +-
 .../stm32f0l0g0/nucleo-f072rb/src/stm32_userleds.c |  10 +-
 .../stm32f0l0g0/nucleo-f091rc/src/stm32_buttons.c  |  30 +-
 .../stm32f0l0g0/nucleo-f091rc/src/stm32_userleds.c |  10 +-
 .../stm32f0l0g0/nucleo-g070rb/src/stm32_buttons.c  |  12 +-
 .../stm32f0l0g0/nucleo-g071rb/src/stm32_buttons.c  |  30 +-
 .../stm32f0l0g0/nucleo-l073rz/src/stm32_buttons.c  |  30 +-
 .../stm32f051-discovery/src/stm32_buttons.c        |  58 +-
 .../stm32f051-discovery/src/stm32_userleds.c       |   5 +-
 .../stm32f072-discovery/src/stm32_buttons.c        |  58 +-
 .../stm32f072-discovery/src/stm32_userleds.c       |   5 +-
 boards/arm/stm32f7/nucleo-144/src/stm32_buttons.c  |  30 +-
 boards/arm/stm32f7/nucleo-144/src/stm32_userleds.c |  10 +-
 .../stm32f7/stm32f746g-disco/src/stm32_buttons.c   |  30 +-
 .../stm32f7/stm32f746g-disco/src/stm32_userleds.c  |   9 +-
 .../stm32f7/stm32f769i-disco/src/stm32_buttons.c   |  27 +-
 .../stm32f7/stm32f769i-disco/src/stm32_userleds.c  |   9 +-
 boards/arm/stm32h7/nucleo-h743zi/scripts/flash.ld  |   6 +
 .../stm32h7/nucleo-h743zi/scripts/kernel.space.ld  |   6 +
 .../arm/stm32h7/nucleo-h743zi/src/stm32_buttons.c  |   6 +-
 .../arm/stm32h7/nucleo-h743zi/src/stm32_userleds.c |  10 +-
 .../arm/stm32h7/stm32h747i-disco/scripts/flash.ld  |   6 +
 .../stm32h747i-disco/scripts/kernel.space.ld       |   7 +
 .../stm32h7/stm32h747i-disco/src/stm32_buttons.c   |   3 +-
 .../stm32h7/stm32h747i-disco/src/stm32_userleds.c  |  10 +-
 .../stm32l4/b-l475e-iot01a/src/stm32_userleds.c    |   7 +-
 .../arm/stm32l4/nucleo-l432kc/src/stm32_buttons.c  |  19 +-
 .../arm/stm32l4/nucleo-l432kc/src/stm32_userleds.c |  10 +-
 .../arm/stm32l4/nucleo-l452re/src/stm32_buttons.c  |  30 +-
 .../arm/stm32l4/nucleo-l452re/src/stm32_userleds.c |  10 +-
 .../arm/stm32l4/nucleo-l476rg/src/stm32_buttons.c  |  30 +-
 .../arm/stm32l4/nucleo-l476rg/src/stm32_userleds.c |  10 +-
 .../arm/stm32l4/nucleo-l496zg/src/stm32_buttons.c  |  30 +-
 .../arm/stm32l4/nucleo-l496zg/src/stm32_userleds.c |  10 +-
 .../arm/stm32l4/stm32l476-mdk/src/stm32_buttons.c  |  24 +-
 .../arm/stm32l4/stm32l476-mdk/src/stm32_userleds.c |   5 +-
 .../stm32l4/stm32l476vg-disco/src/stm32_buttons.c  |  53 +-
 .../stm32l4/stm32l476vg-disco/src/stm32_userleds.c |  14 +-
 .../stm32l4/stm32l4r9ai-disco/src/stm32_buttons.c  |  53 +-
 .../stm32l4/stm32l4r9ai-disco/src/stm32_userleds.c |  13 +-
 .../arm/str71x/olimex-strp711/src/str71_buttons.c  |   4 +-
 boards/arm/tiva/dk-tm4c129x/src/tm4c_buttons.c     |   8 +-
 boards/arm/tiva/dk-tm4c129x/src/tm4c_userleds.c    |   6 +-
 boards/arm/tiva/eagle100/configs/nxflat/defconfig  |   1 -
 boards/arm/tiva/eagle100/scripts/Make.defs         |   3 +
 .../arm/tiva/launchxl-cc1310/src/cc1310_buttons.c  |   3 +-
 .../arm/tiva/launchxl-cc1310/src/cc1310_userleds.c |   5 +-
 .../tiva/launchxl-cc1312r1/src/cc1312_buttons.c    |   3 +-
 .../tiva/launchxl-cc1312r1/src/cc1312_userleds.c   |   5 +-
 .../arm/tiva/tm4c123g-launchpad/src/tm4c_buttons.c |   7 +-
 .../arm/tiva/tm4c1294-launchpad/src/tm4c_buttons.c |   4 +-
 .../tiva/tm4c1294-launchpad/src/tm4c_userleds.c    |   6 +-
 .../tms570/launchxl-tms57004/scripts/flash-sram.ld |   2 -
 .../tms570/launchxl-tms57004/src/tms570_buttons.c  |   7 +-
 .../tms570/launchxl-tms57004/src/tms570_userleds.c |   5 +-
 .../tms570ls31x-usb-kit/scripts/flash-sram.ld      |   2 -
 .../tms570ls31x-usb-kit/src/tms570_buttons.c       |   7 +-
 .../tms570ls31x-usb-kit/src/tms570_userleds.c      |   5 +-
 boards/arm/xmc4/xmc4500-relax/src/xmc4_buttons.c   |   3 +-
 boards/arm/xmc4/xmc4500-relax/src/xmc4_userleds.c  |   5 +-
 boards/arm/xmc4/xmc4700-relax/src/xmc4_buttons.c   |   3 +-
 boards/arm/xmc4/xmc4700-relax/src/xmc4_userleds.c  |   5 +-
 boards/avr/at32uc3/avr32dev1/scripts/avr32dev1.ld  |   2 -
 boards/avr/at32uc3/avr32dev1/src/avr32_buttons.c   |   3 +-
 .../at90usb/micropendous3/scripts/micropendous3.ld |   2 -
 boards/avr/at90usb/teensy-2.0/scripts/flash.ld     |   2 -
 boards/avr/atmega/amber/scripts/amber.ld           |   2 -
 .../avr/atmega/arduino-mega2560/scripts/flash.ld   |   2 -
 boards/avr/atmega/moteino-mega/scripts/ld.script   |   2 -
 boards/hc/m9s12/demo9s12ne64/src/m9s12_buttons.c   |   3 +-
 boards/hc/m9s12/ne64badge/src/m9s12_buttons.c      |   4 +-
 boards/mips/pic32mx/mirtoo/src/pic32_leds.c        |  11 +-
 .../pic32mx/pic32mx-starterkit/src/pic32mx_leds.c  |   5 +-
 boards/mips/pic32mx/pic32mx7mmb/src/pic32_leds.c   |   5 +-
 .../pic32mx/sure-pic32mx/src/pic32mx_buttons.c     |  24 +-
 boards/mips/pic32mx/ubw32/src/pic32_buttons.c      |   4 +-
 boards/mips/pic32mx/ubw32/src/pic32_leds.c         |   5 +-
 .../flipnclick-pic32mz/src/pic32mz_buttons.c       |   4 +-
 .../flipnclick-pic32mz/src/pic32mz_userleds.c      |   5 +-
 .../pic32mz-starterkit/src/pic32mz_buttons.c       |   4 +-
 .../pic32mz-starterkit/src/pic32mz_userleds.c      |   6 +-
 boards/misoc/lm32/misoc/scripts/lm32.ld            |   1 -
 boards/misoc/lm32/misoc/scripts/minerva.ld         |   2 -
 boards/renesas/m16c/skp16c26/src/m16c_buttons.c    |   4 +-
 boards/renesas/rx65n/rx65n/include/board.h         |  14 +-
 .../risc-v/fe310/hifive1-revb/src/fe310_buttons.c  |   7 +-
 boards/risc-v/k210/maix-bit/include/board.h        |  22 +
 boards/risc-v/k210/maix-bit/src/Makefile           |   4 +
 boards/risc-v/k210/maix-bit/src/k210_boot.c        |   2 +
 .../k210/maix-bit/src/k210_leds.c}                 |  44 +-
 boards/sim/sim/sim/scripts/gnu-elf.ld              |   3 -
 boards/sim/sim/sim/src/sim_touchscreen.c           |   4 +-
 boards/z80/ez80/ez80f910200zco/src/ez80_buttons.c  |   4 +-
 drivers/audio/Kconfig                              |  33 +
 drivers/audio/Make.defs                            |   4 +
 drivers/audio/audio_null.c                         |   4 +-
 drivers/audio/{wm8776.c => cs4344.c}               | 839 ++++++++++-----------
 drivers/audio/cs4344.h                             |  98 +++
 drivers/audio/cs43l22.c                            |   4 +-
 drivers/audio/cxd56.c                              | 101 ++-
 drivers/audio/cxd56.h                              |   1 +
 drivers/audio/vs1053.c                             |   4 +-
 drivers/audio/wm8776.c                             |   4 +-
 drivers/audio/wm8904.c                             |   4 +-
 drivers/contactless/pn532.c                        |  58 +-
 drivers/eeprom/i2c_xx24xx.c                        |   2 +-
 drivers/eeprom/spi_xx25xx.c                        |   2 +-
 drivers/input/Kconfig                              |   9 +-
 drivers/input/button_lower.c                       |  19 +-
 drivers/leds/Kconfig                               |   9 +-
 drivers/leds/userled_lower.c                       |  11 +-
 drivers/modem/altair/altmdm.c                      |   1 +
 drivers/modem/u-blox.c                             |  57 +-
 drivers/mtd/mtd_config.c                           |  57 +-
 drivers/net/tun.c                                  |   2 +-
 drivers/timers/timer.c                             |  36 +-
 drivers/timers/watchdog.c                          |   5 +-
 drivers/usbhost/usbhost_xboxcontroller.c           |   2 +-
 include/ctype.h                                    |  37 +-
 include/cxx/cwchar                                 |   1 +
 include/limits.h                                   |  10 +
 include/nuttx/arch.h                               |   4 +-
 include/nuttx/audio/audio.h                        |   2 -
 include/nuttx/audio/cs4344.h                       | 141 ++++
 include/nuttx/board.h                              |  34 +-
 include/nuttx/compiler.h                           |  16 +
 include/nuttx/input/djoystick.h                    |  24 +-
 include/nuttx/leds/userled.h                       |  14 +-
 include/nuttx/sched.h                              |  56 +-
 include/stdint.h                                   |  55 +-
 include/stdio.h                                    |   8 +-
 include/stdlib.h                                   |  29 +-
 include/strings.h                                  |  20 +-
 include/time.h                                     |   4 +-
 include/wchar.h                                    |   8 +-
 libs/libc/libc.csv                                 |  42 +-
 libs/libc/stdio/Make.defs                          |   2 +-
 libs/libc/stdio/lib_fputs.c                        |  10 +-
 libs/libc/stdio/lib_libvscanf.c                    |  88 +--
 libs/libc/stdio/lib_printf.c                       |  49 +-
 libs/libc/stdio/lib_puts.c                         |   2 +-
 .../libc/stdio/lib_tmpfile.c                       |  45 +-
 libs/libc/stdio/lib_vprintf.c                      |  47 +-
 .../xmc4_buttons.c => libs/libc/stdio/lib_vscanf.c |  35 +-
 libs/libc/stdio/lib_vsscanf.c                      |   3 +-
 libs/libc/stdlib/Make.defs                         |   3 +-
 .../xmc4_buttons.c => libs/libc/stdlib/lib_mblen.c |  40 +-
 .../libc/stdlib/lib_mbstowcs.c                     |  40 +-
 libs/libc/stdlib/lib_mbtowc.c                      |   4 +-
 libs/libc/stdlib/lib_mkstemp.c                     |   4 -
 .../libc/stdlib/lib_wcstombs.c                     |  36 +-
 libs/libc/time/lib_localtime.c                     |   4 +-
 libs/libc/wchar/Make.defs                          |   2 +-
 libs/libc/wchar/lib_mbrlen.c                       |   4 +-
 libs/libc/wchar/lib_mbsnrtowcs.c                   |  21 +-
 libs/libc/wchar/lib_mbsrtowcs.c                    |   3 +-
 libs/libc/wchar/lib_wcrtomb.c                      |  10 +-
 libs/libc/wchar/lib_wcsnrtombs.c                   |  49 +-
 .../libc/wchar/lib_wcsrtombs.c                     |  39 +-
 libs/libc/wchar/lib_wctob.c                        |  12 +-
 sched/pthread/pthread_create.c                     |   5 +-
 sched/task/exit.c                                  |  16 +
 sched/task/task_activate.c                         |   5 +-
 sched/task/task_atexit.c                           |  39 +-
 sched/task/task_create.c                           |   7 +-
 sched/task/task_exit.c                             |   6 +-
 sched/task/task_exithook.c                         |  54 +-
 sched/task/task_onexit.c                           |  33 +-
 sched/task/task_restart.c                          |  12 +-
 sched/task/task_vfork.c                            |   8 +-
 tools/checkpatch.sh                                |   2 +-
 tools/incdir.c                                     |   8 +-
 tools/mkdeps.c                                     |  96 ++-
 468 files changed, 6960 insertions(+), 3842 deletions(-)
 create mode 100644 .github/gcc.json
 create mode 100644 .github/nxstyle.json
 copy arch/risc-v/src/k210/{hardware/k210_memorymap.h => k210_fpioa.c} (62%)
 create mode 100644 arch/risc-v/src/k210/k210_fpioa.h
 copy boards/arm/xmc4/xmc4700-relax/src/xmc4_userleds.c => arch/risc-v/src/k210/k210_gpiohs.c (54%)
 copy boards/arm/xmc4/xmc4700-relax/src/xmc4_userleds.c => arch/risc-v/src/k210/k210_gpiohs.h (63%)
 create mode 100644 boards/arm/stm32/olimex-stm32-p407/configs/audio/defconfig
 create mode 100644 boards/arm/stm32/olimex-stm32-p407/src/stm32_cs4344.c
 create mode 100644 boards/arm/stm32/olimex-stm32-p407/src/stm32_djoystick.c
 create mode 100644 boards/arm/stm32/stm32f411-minimum/Kconfig
 create mode 100644 boards/arm/stm32/stm32f411-minimum/README.txt
 create mode 100644 boards/arm/stm32/stm32f411-minimum/configs/nsh/defconfig
 create mode 100644 boards/arm/stm32/stm32f411-minimum/include/board.h
 copy boards/arm/{tiva/eagle100 => stm32/stm32f411-minimum}/scripts/Make.defs (53%)
 create mode 100644 boards/arm/stm32/stm32f411-minimum/scripts/stm32f411ce.ld
 copy {libs/libc/stdlib => boards/arm/stm32/stm32f411-minimum/src}/Make.defs (58%)
 copy sched/task/task_activate.c => boards/arm/stm32/stm32f411-minimum/src/stm32_appinit.c (53%)
 copy boards/arm/{xmc4/xmc4700-relax/src/xmc4_userleds.c => stm32/stm32f411-minimum/src/stm32_autoleds.c} (58%)
 create mode 100644 boards/arm/stm32/stm32f411-minimum/src/stm32_boot.c
 copy sched/task/task_activate.c => boards/arm/stm32/stm32f411-minimum/src/stm32_bringup.c (59%)
 create mode 100644 boards/arm/stm32/stm32f411-minimum/src/stm32_usb.c
 create mode 100644 boards/arm/stm32/stm32f411-minimum/src/stm32f411-minimum.h
 copy boards/{arm/xmc4/xmc4700-relax/src/xmc4_buttons.c => risc-v/k210/maix-bit/src/k210_leds.c} (59%)
 copy drivers/audio/{wm8776.c => cs4344.c} (59%)
 create mode 100644 drivers/audio/cs4344.h
 create mode 100644 include/nuttx/audio/cs4344.h
 copy arch/risc-v/src/k210/hardware/k210_memorymap.h => libs/libc/stdio/lib_tmpfile.c (62%)
 copy boards/arm/xmc4/xmc4700-relax/src/xmc4_buttons.c => libs/libc/stdio/lib_vscanf.c (63%)
 copy boards/arm/xmc4/xmc4700-relax/src/xmc4_buttons.c => libs/libc/stdlib/lib_mblen.c (63%)
 copy boards/arm/xmc4/xmc4700-relax/src/xmc4_buttons.c => libs/libc/stdlib/lib_mbstowcs.c (63%)
 copy boards/arm/xmc4/xmc4700-relax/src/xmc4_buttons.c => libs/libc/stdlib/lib_wcstombs.c (63%)
 copy boards/arm/xmc4/xmc4700-relax/src/xmc4_buttons.c => libs/libc/wchar/lib_wcsrtombs.c (63%)


[incubator-nuttx] 17/31: Added devif_cansend.c (forgotten in commit e485581)

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch SocketCAN
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit c040a0953f720af427cb0f0b04615bc9de3c96fb
Author: Peter van der Perk <pe...@nxp.com>
AuthorDate: Mon Mar 9 13:51:28 2020 +0100

    Added devif_cansend.c (forgotten in commit e485581)
---
 net/devif/devif_cansend.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 113 insertions(+)

diff --git a/net/devif/devif_cansend.c b/net/devif/devif_cansend.c
new file mode 100644
index 0000000..60fdf38
--- /dev/null
+++ b/net/devif/devif_cansend.c
@@ -0,0 +1,113 @@
+/****************************************************************************
+ * net/devif/devif_cansend.c
+ *
+ *   Copyright (C) 2014 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <gn...@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <string.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <nuttx/net/netdev.h>
+
+#if defined(CONFIG_NET_CAN)
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Type Declarations
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Constant Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Constant Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: devif_pkt_send
+ *
+ * Description:
+ *   Called from socket logic in order to send a raw packet in response to
+ *   an xmit or poll request from the network interface driver.
+ *
+ *   This is almost identical to calling devif_send() except that the data to
+ *   be sent is copied into dev->d_buf (vs. dev->d_appdata), since there is
+ *   no header on the data.
+ *
+ * Assumptions:
+ *   Called with the network locked.
+ *
+ ****************************************************************************/
+
+void devif_can_send(FAR struct net_driver_s *dev, FAR const void *buf,
+                    unsigned int len)
+{
+  DEBUGASSERT(dev && len > 0 && len < NETDEV_PKTSIZE(dev));
+
+  /* Copy the data into the device packet buffer */
+
+  memcpy(dev->d_buf, buf, len);
+
+  /* Set the number of bytes to send */
+
+  dev->d_len    = len;
+  dev->d_sndlen = len;
+}
+
+#endif /* CONFIG_NET_CAN */


[incubator-nuttx] 09/31: Added CAN FD driver support

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch SocketCAN
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 58d057ca0816bbf021e9255f68deb1748d6a48b5
Author: Peter van der Perk <pe...@nxp.com>
AuthorDate: Tue Feb 25 08:28:20 2020 +0100

    Added CAN FD driver support
    
    CAN FD receive is working in SocketCAN
---
 arch/arm/src/s32k1xx/s32k1xx_flexcan.c | 433 +++++++++++++++++----------------
 include/nuttx/can/error.h              | 125 ++++++++++
 2 files changed, 351 insertions(+), 207 deletions(-)

diff --git a/arch/arm/src/s32k1xx/s32k1xx_flexcan.c b/arch/arm/src/s32k1xx/s32k1xx_flexcan.c
index 50a5c18..bb0d1d0 100644
--- a/arch/arm/src/s32k1xx/s32k1xx_flexcan.c
+++ b/arch/arm/src/s32k1xx/s32k1xx_flexcan.c
@@ -32,23 +32,14 @@
 #include <debug.h>
 #include <errno.h>
 
-#include <arpa/inet.h>
-
 #include <nuttx/can.h>
 #include <nuttx/wdog.h>
 #include <nuttx/irq.h>
 #include <nuttx/arch.h>
 #include <nuttx/wqueue.h>
 #include <nuttx/signal.h>
-#include <nuttx/net/mii.h>
-#include <nuttx/net/arp.h>
-#include <nuttx/net/phy.h>
 #include <nuttx/net/netdev.h>
 
-#ifdef CONFIG_NET_PKT
-#  include <nuttx/net/pkt.h>
-#endif
-
 #include "up_arch.h"
 #include "chip.h"
 #include "s32k1xx_config.h"
@@ -70,6 +61,7 @@
 
 #if !defined(CONFIG_SCHED_WORKQUEUE)
 #  error Work queue support is required
+   //FIXME maybe for enet not sure for FLEXCAN
 #else
 
   /* Select work queue.  Always use the LP work queue if available.  If not,
@@ -109,17 +101,21 @@
 
 /* Fixme nice variables/constants */
 
-#define RXMBCOUNT                   6
-#define FILTERCOUNT                 0
-#define RXANDFILTERMBCOUNT          (RXMBCOUNT + FILTERCOUNT)
-#define TXMBCOUNT                   12 //???????????? why 12 idk it works
-#define TOTALMBCOUNT                RXANDFILTERMBCOUNT + TXMBCOUNT
-#define TXMBMASK                    (((1 << TXMBCOUNT)-1) << RXANDFILTERMBCOUNT)
+#define CAN_FD
+
+#define RXMBCOUNT                   5
+#define TXMBCOUNT                   2
+#define TOTALMBCOUNT                RXMBCOUNT + TXMBCOUNT
+
+#define IFLAG1_RX                   ((1 << RXMBCOUNT)-1)
+#define IFLAG1_TX                   (((1 << TXMBCOUNT)-1) << RXMBCOUNT)
 
 #define CAN_FIFO_NE                 (1 << 5)
 #define CAN_FIFO_OV                 (1 << 6)
 #define CAN_FIFO_WARN               (1 << 7)
-#define FIFO_IFLAG1                 (CAN_FIFO_NE | CAN_FIFO_WARN | CAN_FIFO_OV)
+
+/* Interrupt flags for RX fifo */
+#define IFLAG1_RXFIFO               (CAN_FIFO_NE | CAN_FIFO_WARN | CAN_FIFO_OV)
 
 static int peak_tx_mailbox_index_ = 0;
 
@@ -162,40 +158,14 @@ static int peak_tx_mailbox_index_ = 0;
 #define FLEXCAN_ALIGN_MASK   (FLEXCAN_ALIGN - 1)
 #define FLEXCAN_ALIGN_UP(n)  (((n) + FLEXCAN_ALIGN_MASK) & ~FLEXCAN_ALIGN_MASK)
 
-/* TX timeout = 1 minute */
-
-#define S32K1XX_TXTIMEOUT   (60*CLK_TCK)
-#define MII_MAXPOLLS      (0x1ffff)
-#define LINK_WAITUS       (500*1000)
-#define LINK_NLOOPS       (10)
-
-/* Interrupt groups */
-
-#define RX_INTERRUPTS     (FLEXCAN_INT_RXF | FLEXCAN_INT_RXB)
-#define TX_INTERRUPTS      FLEXCAN_INT_TXF
-#define ERROR_INTERRUPTS  (FLEXCAN_INT_UN    | FLEXCAN_INT_RL   | FLEXCAN_INT_LC | \
-                           FLEXCAN_INT_EBERR | FLEXCAN_INT_BABT | FLEXCAN_INT_BABR)
-
-/* The subset of errors that require us to reset the hardware - this list
- * may need to be revisited if it's found that some error above leads to a
- * locking up of the Ethernet interface.
- */
-
-#define CRITICAL_ERROR    (FLEXCAN_INT_UN | FLEXCAN_INT_RL | FLEXCAN_INT_EBERR )
-
-/* This is a helper pointer for accessing the contents of the Ethernet header */
-
-#define BUF ((struct eth_hdr_s *)priv->dev.d_buf)
-
-#define S32K1XX_BUF_SIZE  FLEXCAN_ALIGN_UP(CONFIG_NET_ETH_PKTSIZE)
 
 /****************************************************************************
  * Private Types
  ****************************************************************************/
 
-union txcs_e
+union cs_e
 {
-  volatile uint32_t w;
+  volatile uint32_t cs;
   struct
   {
     volatile uint32_t time_stamp : 16;
@@ -205,21 +175,10 @@ union txcs_e
     volatile uint32_t srr : 1;
     volatile uint32_t res : 1;
     volatile uint32_t code : 4;
-    volatile uint32_t res2 : 4;
-  };
-};
-
-union rxcs_e
-{
-  volatile uint32_t cs;
-  struct
-  {
-    volatile uint32_t time_stamp : 16;
-    volatile uint32_t dlc : 4;
-    volatile uint32_t rtr : 1;
-    volatile uint32_t ide : 1;
-    volatile uint32_t srr : 1;
-    volatile uint32_t res : 9;
+    volatile uint32_t res2 : 1;
+    volatile uint32_t esi : 1;
+    volatile uint32_t brs : 1;
+    volatile uint32_t edl : 1;
   };
 };
 
@@ -241,33 +200,25 @@ union id_e
 
 union data_e
 {
-  volatile uint32_t l;
-  volatile uint32_t h;
+  volatile uint32_t w00;
   struct
   {
-    volatile uint32_t b3 : 8;
-    volatile uint32_t b2 : 8;
-    volatile uint32_t b1 : 8;
-    volatile uint32_t b0 : 8;
-    volatile uint32_t b7 : 8;
-    volatile uint32_t b6 : 8;
-    volatile uint32_t b5 : 8;
-    volatile uint32_t b4 : 8;
+    volatile uint32_t b03 : 8;
+    volatile uint32_t b02 : 8;
+    volatile uint32_t b01 : 8;
+    volatile uint32_t b00 : 8;
   };
 };
 
-struct mbtx_s
+struct mb_s
 {
-  union txcs_e cs;
+  union cs_e cs;
   union id_e id;
-  union data_e data;
-};
-
-struct mbrx_s
-{
-  union rxcs_e cs;
-  union id_e id;
-  union data_e data;
+#ifdef CAN_FD
+  union data_e data[16];
+#else
+  union data_e data[2];
+#endif
 };
 
 /* The s32k1xx_driver_s encapsulates all state information for a single
@@ -292,8 +243,8 @@ struct s32k1xx_driver_s
 
   struct net_driver_s dev;     /* Interface understood by the network */
 
-  struct mbrx_s *rx;
-  struct mbtx_s *tx;
+  struct mb_s *rx;
+  struct mb_s *tx;
 };
 
 /****************************************************************************
@@ -324,6 +275,28 @@ static inline uint16_t s32k1xx_swap16(uint16_t value);
 #endif
 #endif
 
+/****************************************************************************
+ * Name: arm_clz
+ *
+ * Description:
+ *   Access to CLZ instructions
+ *
+ * Input Parameters:
+ *   value - The value to perform the Count Leading Zeros operation on
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static inline uint32_t arm_clz(unsigned int value)
+{
+  uint32_t ret;
+
+  __asm__ __volatile__ ("clz %0, %1" : "=r"(ret) : "r"(value));
+  return ret;
+}
+
 /* Common TX logic */
 
 static bool s32k1xx_txringfull(FAR struct s32k1xx_driver_s *priv);
@@ -340,8 +313,8 @@ static uint32_t s32k1xx_waitmcr_change(uint32_t mask,
 /* Interrupt handling */
 
 static void s32k1xx_dispatch(FAR struct s32k1xx_driver_s *priv);
-static void s32k1xx_receive(FAR struct s32k1xx_driver_s *priv);
-static void s32k1xx_txdone(FAR struct s32k1xx_driver_s *priv);
+static void s32k1xx_receive(FAR struct s32k1xx_driver_s *priv, uint32_t flags);
+static void s32k1xx_txdone(FAR struct s32k1xx_driver_s *priv, uint32_t flags);
 
 static void s32k1xx_flexcan_interrupt_work(FAR void *arg);
 static int  s32k1xx_flexcan_interrupt(int irq, FAR void *context,
@@ -363,12 +336,6 @@ static int  s32k1xx_ifdown(struct net_driver_s *dev);
 static void s32k1xx_txavail_work(FAR void *arg);
 static int  s32k1xx_txavail(struct net_driver_s *dev);
 
-#ifdef CONFIG_NET_MCASTGROUP
-static int  s32k1xx_addmac(struct net_driver_s *dev,
-                           FAR const uint8_t *mac);
-static int  s32k1xx_rmmac(struct net_driver_s *dev, FAR const uint8_t *mac);
-#endif
-
 #ifdef CONFIG_NETDEV_IOCTL
 static int  s32k1xx_ioctl(struct net_driver_s *dev, int cmd,
                           unsigned long arg);
@@ -456,11 +423,12 @@ static int s32k1xx_transmit(FAR struct s32k1xx_driver_s *priv)
   if ((getreg32(S32K1XX_CAN0_ESR2) & (CAN_ESR2_IMB | CAN_ESR2_VPS)) ==
       (CAN_ESR2_IMB | CAN_ESR2_VPS))
     {
-      mbi = (getreg32(S32K1XX_CAN0_ESR2) & CAN_ESR2_LPTM_MASK) >>
-            CAN_ESR2_LPTM_SHIFT;
+      mbi  = ((getreg32(S32K1XX_CAN0_ESR2) &
+    		CAN_ESR2_LPTM_MASK) >> CAN_ESR2_LPTM_SHIFT);
+      mbi -= RXMBCOUNT;
     }
 
-  uint32_t mb_bit = 1 << (RXANDFILTERMBCOUNT + mbi);
+  uint32_t mb_bit = 1 << (RXMBCOUNT + mbi);
 
   while (mbi < TXMBCOUNT)
     {
@@ -474,7 +442,7 @@ static int s32k1xx_transmit(FAR struct s32k1xx_driver_s *priv)
       mbi++;
     }
 
-  if ((mbi - RXANDFILTERMBCOUNT) == TXMBCOUNT)
+  if (mbi == TXMBCOUNT)
     {
       nwarn("No TX MB available mbi %i\r\n", mbi);
       return 0;       /* No transmission for you! */
@@ -483,9 +451,9 @@ static int s32k1xx_transmit(FAR struct s32k1xx_driver_s *priv)
   peak_tx_mailbox_index_ =
     (peak_tx_mailbox_index_ > mbi ? peak_tx_mailbox_index_ : mbi);
 
-  union txcs_e cs;
+  union cs_e cs;
   cs.code = CAN_TXMB_DATAORREMOTE;
-  struct mbtx_s *mb = &priv->tx[mbi];
+  struct mb_s *mb = &priv->tx[mbi];
   mb->cs.code = CAN_TXMB_INACTIVE;
 
   if (0) /* FIXME detect Std or Ext id */
@@ -506,14 +474,14 @@ static int s32k1xx_transmit(FAR struct s32k1xx_driver_s *priv)
 
   /* FIXME endian swap instruction or somekind takes 1.5us right now */
 
-  mb->data.b0 = frame->data[0];
-  mb->data.b1 = frame->data[1];
-  mb->data.b2 = frame->data[2];
-  mb->data.b3 = frame->data[3];
-  mb->data.b4 = frame->data[4];
-  mb->data.b5 = frame->data[5];
-  mb->data.b6 = frame->data[6];
-  mb->data.b7 = frame->data[7];
+  mb->data[0].b00 = frame->data[0];
+  mb->data[0].b01 = frame->data[1];
+  mb->data[0].b02 = frame->data[2];
+  mb->data[0].b03 = frame->data[3];
+  mb->data[1].b00 = frame->data[4];
+  mb->data[1].b01 = frame->data[5];
+  mb->data[1].b02 = frame->data[6];
+  mb->data[1].b03 = frame->data[7];
 
 #if 0
   /* Registering the pending transmission so we can track its deadline and
@@ -646,77 +614,142 @@ static inline void s32k1xx_dispatch(FAR struct s32k1xx_driver_s *priv)
  *
  ****************************************************************************/
 
-static void s32k1xx_receive(FAR struct s32k1xx_driver_s *priv)
+static void s32k1xx_receive(FAR struct s32k1xx_driver_s *priv, uint32_t flags)
 {
   #warning Missing logic
+  uint32_t regval;
+
   s32k1xx_gpiowrite(PIN_PORTD | PIN31, 1);
 
-  struct can_frame frame;
-  uint32_t flags = getreg32(S32K1XX_CAN0_IFLAG1);
 
-  if ((flags & FIFO_IFLAG1) == 0)
+  //FIXME naive what if multiple flags are high??
+  uint32_t mb_index = arm_clz(flags);
+
+  if (mb_index)
     {
-      /* Weird, IRQ is here but no data to read */
+      struct mb_s *rf = &priv->rx[31 - mb_index];
 
-      return;
-    }
+      /* Read the frame contents */
 
-  if (flags & CAN_FIFO_OV)
-    {
-#if 0
-      error_cnt_++;
-#endif
-      putreg32(CAN_FIFO_OV, S32K1XX_CAN0_IFLAG1);
-    }
+      if(rf->cs.edl) /* CAN FD frame */
+        {
 
-  if (flags & CAN_FIFO_WARN)
-    {
-#if 0
-      fifo_warn_cnt_++;
-#endif
-      putreg32(CAN_FIFO_WARN, S32K1XX_CAN0_IFLAG1);
-    }
+    	  struct canfd_frame frame;
 
-  if (flags & CAN_FIFO_NE)
-    {
-      struct mbrx_s *rf = priv->rx;
+          if (rf->cs.ide)
+            {
+              frame.can_id = MASKEXTID & rf->id.ext;
+              frame.can_id |= FLAGEFF;
+            }
+          else
+            {
+              frame.can_id = MASKSTDID & rf->id.std;
+            }
 
-      /* Read the frame contents */
+          if (rf->cs.rtr)
+            {
+              frame.can_id |= FLAGRTR;
+            }
 
-      if (rf->cs.ide)
-        {
-          frame.can_id = MASKEXTID & rf->id.ext;
-          frame.can_id |= FLAGEFF;
+          if(rf->cs.dlc < 9){
+              frame.len = rf->cs.dlc;
+          } else {
+        	  switch(rf->cs.dlc)
+        	    {
+        	     case 9:
+        	       frame.len = 12;
+        	       break;
+
+        	     case 10:
+        	       frame.len = 16;
+        	       break;
+
+        	     case 11:
+        	       frame.len = 20;
+        	       break;
+
+        	     case 12:
+        	       frame.len = 24;
+        	       break;
+
+        	     case 13:
+        	       frame.len = 32;
+        	       break;
+
+        	     case 14:
+        	       frame.len = 48;
+        	       break;
+
+        	     case 15:
+        	       frame.len = 64;
+        	       break;
+        	    }
+          }
+
+    	  int j = 0;
+          for(int i = 0; i < (frame.len + 4 - 1) / 4; i++)
+            {
+              frame.data[0+j] = rf->data[i].b00;
+              frame.data[1+j] = rf->data[i].b01;
+              frame.data[2+j] = rf->data[i].b02;
+              frame.data[3+j] = rf->data[i].b03;
+              j = j + 4;
+            }
+
+          /* Clear MB interrupt flag */
+          regval  = getreg32(S32K1XX_CAN0_IFLAG1);
+          regval |= (1 << mb_index);
+          putreg32(regval, S32K1XX_CAN0_IFLAG1);
+
+          /* Copy the buffer pointer to priv->dev.d_buf.  Set amount of data
+           * in priv->dev.d_len
+           */
+
+          priv->dev.d_len = sizeof(struct canfd_frame);
+          priv->dev.d_buf = (uint8_t *)s32k1xx_swap32((uint32_t)&frame); /* FIXME */
         }
-      else
+      else /* CAN 2.0 Frame */
         {
-          frame.can_id = MASKSTDID & rf->id.std;
-        }
+    	  struct can_frame frame;
 
-      if (rf->cs.rtr)
-        {
-          frame.can_id |= FLAGRTR;
-        }
+          if (rf->cs.ide)
+            {
+              frame.can_id = MASKEXTID & rf->id.ext;
+              frame.can_id |= FLAGEFF;
+            }
+          else
+            {
+              frame.can_id = MASKSTDID & rf->id.std;
+            }
 
-      frame.can_dlc = rf->cs.dlc;
+          if (rf->cs.rtr)
+            {
+              frame.can_id |= FLAGRTR;
+            }
 
-      frame.data[0] = rf->data.b0;
-      frame.data[1] = rf->data.b1;
-      frame.data[2] = rf->data.b2;
-      frame.data[3] = rf->data.b3;
-      frame.data[4] = rf->data.b4;
-      frame.data[5] = rf->data.b5;
-      frame.data[6] = rf->data.b6;
-      frame.data[7] = rf->data.b7;
+          frame.can_dlc = rf->cs.dlc;
 
-      putreg32(CAN_FIFO_NE, S32K1XX_CAN0_IFLAG1);
+          frame.data[0] = rf->data[0].b00;
+          frame.data[1] = rf->data[0].b01;
+          frame.data[2] = rf->data[0].b02;
+          frame.data[3] = rf->data[0].b03;
+          frame.data[4] = rf->data[1].b00;
+          frame.data[5] = rf->data[1].b01;
+          frame.data[6] = rf->data[1].b02;
+          frame.data[7] = rf->data[1].b03;
 
-      /* Copy the buffer pointer to priv->dev.d_buf.  Set amount of data
-       * in priv->dev.d_len
-       */
+          /* Clear MB interrupt flag */
+          regval  = getreg32(S32K1XX_CAN0_IFLAG1);
+          regval |= (1 << mb_index);
+          putreg32(regval, S32K1XX_CAN0_IFLAG1);
 
-      priv->dev.d_len = sizeof(struct can_frame);
-      priv->dev.d_buf = (uint8_t *)s32k1xx_swap32((uint32_t)&frame); /* FIXME */
+          /* Copy the buffer pointer to priv->dev.d_buf.  Set amount of data
+           * in priv->dev.d_len
+           */
+
+          priv->dev.d_len = sizeof(struct can_frame);
+          priv->dev.d_buf = (uint8_t *)s32k1xx_swap32((uint32_t)&frame); /* FIXME */
+        }
 
       /* Invalidate the buffer so that the correct packet will be re-read
        * from memory when the packet content is accessed.
@@ -753,24 +786,21 @@ static void s32k1xx_receive(FAR struct s32k1xx_driver_s *priv)
  *
  ****************************************************************************/
 
-static void s32k1xx_txdone(FAR struct s32k1xx_driver_s *priv)
+static void s32k1xx_txdone(FAR struct s32k1xx_driver_s *priv, uint32_t flags)
 {
   #warning Missing logic
 
-  uint32_t tx_iflags;
-  tx_iflags = getreg32(S32K1XX_CAN0_IFLAG1) & TXMBMASK;
-
   /* FIXME process aborts */
 
   /* Process TX completions */
 
   uint32_t mb_bit = 1 << RXMBCOUNT;
-  for (uint32_t mbi = 0; tx_iflags && mbi < TXMBCOUNT; mbi++)
+  for (uint32_t mbi = 0; flags && mbi < TXMBCOUNT; mbi++)
     {
-      if (tx_iflags & mb_bit)
+      if (flags & mb_bit)
         {
           putreg32(mb_bit, S32K1XX_CAN0_IFLAG1);
-          tx_iflags &= ~mb_bit;
+          flags &= ~mb_bit;
 #if 0
           const bool txok = priv->tx[mbi].cs.code != CAN_TXMB_ABORT;
           handleTxMailboxInterrupt(mbi, txok, utc_usec);
@@ -829,19 +859,19 @@ static int s32k1xx_flexcan_interrupt(int irq, FAR void *context, FAR void *arg)
   FAR struct s32k1xx_driver_s *priv = &g_flexcan[0];
   uint32_t flags;
   flags  = getreg32(S32K1XX_CAN0_IFLAG1);
-  flags &= FIFO_IFLAG1;
+  flags &= IFLAG1_RX;
 
   if (flags)
     {
-      s32k1xx_receive(priv);
+      s32k1xx_receive(priv, flags);
     }
 
   flags  = getreg32(S32K1XX_CAN0_IFLAG1);
-  flags &= TXMBMASK;
+  flags &= IFLAG1_TX;
 
   if (flags)
     {
-      s32k1xx_txdone(priv);
+      s32k1xx_txdone(priv, flags);
     }
 }
 
@@ -1271,38 +1301,18 @@ static int s32k1xx_initialize(struct s32k1xx_driver_s *priv)
       return -1;
     }
 
-#if 0
-  regval  = getreg32(S32K1XX_CAN0_CTRL1);
-  regval |= ((0  << CAN_CTRL1_PRESDIV_SHIFT) & CAN_CTRL1_PRESDIV_MASK) |
-            ((46 << CAN_CTRL1_ROPSEG_SHIFT) & CAN_CTRL1_ROPSEG_MASK) |
-            ((18 << CAN_CTRL1_PSEG1_SHIFT) & CAN_CTRL1_PSEG1_MASK) |
-            ((12 << CAN_CTRL1_PSEG2_SHIFT) & CAN_CTRL1_PSEG2_MASK) |
-            ((12 << CAN_CTRL1_RJW_SHIFT) & CAN_CTRL1_RJW_MASK) |
-            CAN_CTRL1_ERRMSK |
-            CAN_CTRL1_TWRNMSK |
-            CAN_CTRL1_RWRNMSK;
-
-  putreg32(regval, S32K1XX_CAN0_CTRL1);
-#endif
-
-#define BIT_METHOD2
-#ifdef BIT_METHOD2
-  /* CAN Bit Timing (CBT) configuration for a nominal phase of 1 Mbit/s
-   * with 80 time quantas,in accordance with Bosch 2012 specification,
-   * sample point at 83.75%
-   */
 
+  /* Based on 80Mhz BUS clock calc through S32DS */
   regval  = getreg32(S32K1XX_CAN0_CBT);
   regval |= CAN_CBT_BTF |          /* Enable extended bit timing configurations
                                     * for CAN-FD for setting up separately
                                     * nominal and data phase */
-            CAN_CBT_EPRESDIV(0) |  /* Prescaler divisor factor of 1 */
-            CAN_CBT_EPROPSEG(46) | /* Propagation segment of 47 time quantas */
-            CAN_CBT_EPSEG1(18) |   /* Phase buffer segment 1 of 19 time quantas */
-            CAN_CBT_EPSEG2(12) |   /* Phase buffer segment 2 of 13 time quantas */
-            CAN_CBT_ERJW(12);      /* Resynchronization jump width same as PSEG2 */
+            CAN_CBT_EPRESDIV(3) |  /* Prescaler divisor factor of 3 */
+            CAN_CBT_EPROPSEG(7) | /* Propagation segment of 7 time quantas */
+            CAN_CBT_EPSEG1(6) |   /* Phase buffer segment 1 of 6 time quantas */
+            CAN_CBT_EPSEG2(3) |   /* Phase buffer segment 2 of 3 time quantas */
+            CAN_CBT_ERJW(1);      /* Resynchronization jump width */
   putreg32(regval, S32K1XX_CAN0_CBT);
-#endif
 
 #ifdef CAN_FD
   /* Enable CAN FD feature */
@@ -1311,17 +1321,14 @@ static int s32k1xx_initialize(struct s32k1xx_driver_s *priv)
   regval |= CAN_MCR_FDEN;
   putreg32(regval, S32K1XX_CAN0_MCR);
 
-  /* CAN-FD Bit Timing (FDCBT) for a data phase of 4 Mbit/s with 20 time quantas,
-   * in accordance with Bosch 2012 specification, sample point at 75%
-   */
-
+  /* Based on 80Mhz BUS clock calc through S32DS */
   regval  = getreg32(S32K1XX_CAN0_FDCBT);
   regval |= CAN_FDCBT_FPRESDIV(0) | /* Prescaler divisor factor of 1 */
-            CAN_FDCBT_FPROPSEG(7) | /* Propagation semgment of 7 time quantas
+            CAN_FDCBT_FPROPSEG(15) | /* Propagation semgment of 7 time quantas
                                      * (only register that doesn't add 1) */
-            CAN_FDCBT_FPSEG1(6) |   /* Phase buffer segment 1 of 7 time quantas */
-            CAN_FDCBT_FPSEG2(4) |   /* Phase buffer segment 2 of 5 time quantas */
-            CAN_FDCBT_FRJW(4);      /* Resynchorinzation jump width same as PSEG2 */
+            CAN_FDCBT_FPSEG1(1) |   /* Phase buffer segment 1 of 7 time quantas */
+            CAN_FDCBT_FPSEG2(1) |   /* Phase buffer segment 2 of 5 time quantas */
+            CAN_FDCBT_FRJW(1);      /* Resynchorinzation jump width same as PSEG2 */
   putreg32(regval, S32K1XX_CAN0_FDCBT);
 
   /* Additional CAN-FD configurations */
@@ -1351,8 +1358,20 @@ static int s32k1xx_initialize(struct s32k1xx_driver_s *priv)
       putreg32(0, S32K1XX_CAN0_RXIMR(i));
     }
 
-  putreg32(FIFO_IFLAG1 | TXMBMASK, S32K1XX_CAN0_IFLAG1);
-  putreg32(FIFO_IFLAG1, S32K1XX_CAN0_IMASK1);
+  for (i = 0; i < RXMBCOUNT; i++)
+    {
+      ninfo("Set MB%i to receive %p\r\n", i, &priv->rx[i]);
+      priv->rx[i].cs.edl = 0x1;
+      priv->rx[i].cs.brs = 0x1;
+      priv->rx[i].cs.esi = 0x0;
+      priv->rx[i].cs.code = 4;
+      priv->rx[i].cs.srr = 0x0;
+      priv->rx[i].cs.ide = 0x1;
+      priv->rx[i].cs.rtr = 0x0;
+    }
+
+  putreg32(IFLAG1_RX, S32K1XX_CAN0_IFLAG1);
+  putreg32(IFLAG1_RX, S32K1XX_CAN0_IMASK1);
 
   /* Exit freeze mode */
 
@@ -1432,12 +1451,12 @@ static void s32k1xx_reset(struct s32k1xx_driver_s *priv)
       ninfo("MB %i %p\r\n", i, &priv->rx[i].id.w);
       priv->rx[i].cs.cs = 0x0;
       priv->rx[i].id.w = 0x0;
-      priv->rx[i].data.l = 0x0;
-      priv->rx[i].data.h = 0x0;
+      priv->rx[i].data[0].w00 = 0x0;
+      priv->rx[i].data[1].w00 = 0x0;
     }
 
   regval  = getreg32(S32K1XX_CAN0_MCR);
-  regval |= CAN_MCR_RFEN | CAN_MCR_SLFWAK | CAN_MCR_WRNEN | CAN_MCR_SRXDIS |
+  regval |= CAN_MCR_SLFWAK | CAN_MCR_WRNEN | CAN_MCR_SRXDIS |
             CAN_MCR_IRMQ | CAN_MCR_AEN |
             (((TOTALMBCOUNT - 1) << CAN_MCR_MAXMB_SHIFT) & CAN_MCR_MAXMB_MASK);
   putreg32(regval, S32K1XX_CAN0_MCR);
@@ -1546,9 +1565,9 @@ int s32k1xx_netinitialize(int intf)
 
   priv->txpoll        = wd_create();       /* Create periodic poll timer */
   priv->txtimeout     = wd_create();       /* Create TX timeout timer */
-  priv->rx            = (struct mbrx_s *)(S32K1XX_CAN0_MB);
-  priv->tx            = (struct mbtx_s *)(S32K1XX_CAN0_MB +
-                          (sizeof(struct mbrx_s) * RXMBCOUNT));
+  priv->rx            = (struct mb_s *)(S32K1XX_CAN0_MB);
+  priv->tx            = (struct mb_s *)(S32K1XX_CAN0_MB +
+                          (sizeof(struct mb_s) * RXMBCOUNT));
 
   /* Put the interface in the down state.  This usually amounts to resetting
    * the device and/or calling s32k1xx_ifdown().
diff --git a/include/nuttx/can/error.h b/include/nuttx/can/error.h
new file mode 100644
index 0000000..3463328
--- /dev/null
+++ b/include/nuttx/can/error.h
@@ -0,0 +1,125 @@
+/* SPDX-License-Identifier: ((GPL-2.0-only WITH Linux-syscall-note) OR BSD-3-Clause) */
+/*
+ * linux/can/error.h
+ *
+ * Definitions of the CAN error messages to be filtered and passed to the user.
+ *
+ * Author: Oliver Hartkopp <ol...@volkswagen.de>
+ * Copyright (c) 2002-2007 Volkswagen Group Electronic Research
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Volkswagen nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * Alternatively, provided that this notice is retained in full, this
+ * software may be distributed under the terms of the GNU General
+ * Public License ("GPL") version 2, in which case the provisions of the
+ * GPL apply INSTEAD OF those given above.
+ *
+ * The provided data structures and external interfaces from this code
+ * are not restricted to be used by modules with a GPL compatible license.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ */
+
+#ifndef _UAPI_CAN_ERROR_H
+#define _UAPI_CAN_ERROR_H
+
+#define CAN_ERR_DLC 8 /* dlc for error message frames */
+
+/* error class (mask) in can_id */
+#define CAN_ERR_TX_TIMEOUT   0x00000001U /* TX timeout (by netdevice driver) */
+#define CAN_ERR_LOSTARB      0x00000002U /* lost arbitration    / data[0]    */
+#define CAN_ERR_CRTL         0x00000004U /* controller problems / data[1]    */
+#define CAN_ERR_PROT         0x00000008U /* protocol violations / data[2..3] */
+#define CAN_ERR_TRX          0x00000010U /* transceiver status  / data[4]    */
+#define CAN_ERR_ACK          0x00000020U /* received no ACK on transmission */
+#define CAN_ERR_BUSOFF       0x00000040U /* bus off */
+#define CAN_ERR_BUSERROR     0x00000080U /* bus error (may flood!) */
+#define CAN_ERR_RESTARTED    0x00000100U /* controller restarted */
+
+/* arbitration lost in bit ... / data[0] */
+#define CAN_ERR_LOSTARB_UNSPEC   0x00 /* unspecified */
+				      /* else bit number in bitstream */
+
+/* error status of CAN-controller / data[1] */
+#define CAN_ERR_CRTL_UNSPEC      0x00 /* unspecified */
+#define CAN_ERR_CRTL_RX_OVERFLOW 0x01 /* RX buffer overflow */
+#define CAN_ERR_CRTL_TX_OVERFLOW 0x02 /* TX buffer overflow */
+#define CAN_ERR_CRTL_RX_WARNING  0x04 /* reached warning level for RX errors */
+#define CAN_ERR_CRTL_TX_WARNING  0x08 /* reached warning level for TX errors */
+#define CAN_ERR_CRTL_RX_PASSIVE  0x10 /* reached error passive status RX */
+#define CAN_ERR_CRTL_TX_PASSIVE  0x20 /* reached error passive status TX */
+				      /* (at least one error counter exceeds */
+				      /* the protocol-defined level of 127)  */
+#define CAN_ERR_CRTL_ACTIVE      0x40 /* recovered to error active state */
+
+/* error in CAN protocol (type) / data[2] */
+#define CAN_ERR_PROT_UNSPEC      0x00 /* unspecified */
+#define CAN_ERR_PROT_BIT         0x01 /* single bit error */
+#define CAN_ERR_PROT_FORM        0x02 /* frame format error */
+#define CAN_ERR_PROT_STUFF       0x04 /* bit stuffing error */
+#define CAN_ERR_PROT_BIT0        0x08 /* unable to send dominant bit */
+#define CAN_ERR_PROT_BIT1        0x10 /* unable to send recessive bit */
+#define CAN_ERR_PROT_OVERLOAD    0x20 /* bus overload */
+#define CAN_ERR_PROT_ACTIVE      0x40 /* active error announcement */
+#define CAN_ERR_PROT_TX          0x80 /* error occurred on transmission */
+
+/* error in CAN protocol (location) / data[3] */
+#define CAN_ERR_PROT_LOC_UNSPEC  0x00 /* unspecified */
+#define CAN_ERR_PROT_LOC_SOF     0x03 /* start of frame */
+#define CAN_ERR_PROT_LOC_ID28_21 0x02 /* ID bits 28 - 21 (SFF: 10 - 3) */
+#define CAN_ERR_PROT_LOC_ID20_18 0x06 /* ID bits 20 - 18 (SFF: 2 - 0 )*/
+#define CAN_ERR_PROT_LOC_SRTR    0x04 /* substitute RTR (SFF: RTR) */
+#define CAN_ERR_PROT_LOC_IDE     0x05 /* identifier extension */
+#define CAN_ERR_PROT_LOC_ID17_13 0x07 /* ID bits 17-13 */
+#define CAN_ERR_PROT_LOC_ID12_05 0x0F /* ID bits 12-5 */
+#define CAN_ERR_PROT_LOC_ID04_00 0x0E /* ID bits 4-0 */
+#define CAN_ERR_PROT_LOC_RTR     0x0C /* RTR */
+#define CAN_ERR_PROT_LOC_RES1    0x0D /* reserved bit 1 */
+#define CAN_ERR_PROT_LOC_RES0    0x09 /* reserved bit 0 */
+#define CAN_ERR_PROT_LOC_DLC     0x0B /* data length code */
+#define CAN_ERR_PROT_LOC_DATA    0x0A /* data section */
+#define CAN_ERR_PROT_LOC_CRC_SEQ 0x08 /* CRC sequence */
+#define CAN_ERR_PROT_LOC_CRC_DEL 0x18 /* CRC delimiter */
+#define CAN_ERR_PROT_LOC_ACK     0x19 /* ACK slot */
+#define CAN_ERR_PROT_LOC_ACK_DEL 0x1B /* ACK delimiter */
+#define CAN_ERR_PROT_LOC_EOF     0x1A /* end of frame */
+#define CAN_ERR_PROT_LOC_INTERM  0x12 /* intermission */
+
+/* error status of CAN-transceiver / data[4] */
+/*                                             CANH CANL */
+#define CAN_ERR_TRX_UNSPEC             0x00 /* 0000 0000 */
+#define CAN_ERR_TRX_CANH_NO_WIRE       0x04 /* 0000 0100 */
+#define CAN_ERR_TRX_CANH_SHORT_TO_BAT  0x05 /* 0000 0101 */
+#define CAN_ERR_TRX_CANH_SHORT_TO_VCC  0x06 /* 0000 0110 */
+#define CAN_ERR_TRX_CANH_SHORT_TO_GND  0x07 /* 0000 0111 */
+#define CAN_ERR_TRX_CANL_NO_WIRE       0x40 /* 0100 0000 */
+#define CAN_ERR_TRX_CANL_SHORT_TO_BAT  0x50 /* 0101 0000 */
+#define CAN_ERR_TRX_CANL_SHORT_TO_VCC  0x60 /* 0110 0000 */
+#define CAN_ERR_TRX_CANL_SHORT_TO_GND  0x70 /* 0111 0000 */
+#define CAN_ERR_TRX_CANL_SHORT_TO_CANH 0x80 /* 1000 0000 */
+
+/* controller specific additional information / data[5..7] */
+
+#endif /* _UAPI_CAN_ERROR_H */


[incubator-nuttx] 24/31: Code style fixes 3

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch SocketCAN
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 6dc8e9d006fbe459023c9eeb2586b9869297cade
Author: Jari van Ewijk <ja...@nxp.com>
AuthorDate: Fri Mar 13 17:27:21 2020 +0100

    Code style fixes 3
---
 net/can/can.h            |  13 ++--
 net/can/can_callback.c   |  21 +++---
 net/can/can_conn.c       |   8 +-
 net/can/can_getsockopt.c |  18 +++--
 net/can/can_recvfrom.c   | 189 +++++++++++++++++++++++++----------------------
 net/can/can_send.c       |  36 ++++-----
 net/can/can_setsockopt.c |  51 ++++++-------
 net/can/can_sockif.c     |  14 ++--
 8 files changed, 185 insertions(+), 165 deletions(-)

diff --git a/net/can/can.h b/net/can/can.h
index c74fca4..7c6b614 100644
--- a/net/can/can.h
+++ b/net/can/can.h
@@ -104,22 +104,20 @@ struct can_conn_s
    */
 
   struct can_poll_s pollinfo[4]; /* FIXME make dynamic */
-  
+
 #ifdef CONFIG_NET_CANPROTO_OPTIONS
   int32_t loopback;
   int32_t recv_own_msgs;
   int32_t fd_frames;
   struct can_filter filters[CONFIG_NET_CAN_RAW_FILTER_MAX];
   int32_t filter_count;
-  
+
   /* TODO add filter support */
 #endif
-  
+
 #ifdef CONFIG_NET_TIMESTAMP
   FAR struct socket *psock; /* Needed to get SO_TIMESTAMP value */
 #endif
-
-  
 };
 
 /****************************************************************************
@@ -168,8 +166,8 @@ FAR struct can_conn_s *can_alloc(void);
  * Name: can_free()
  *
  * Description:
- *   Free a NetLink connection structure that is no longer in use. This should
- *   be done by the implementation of close().
+ *   Free a NetLink connection structure that is no longer in use. This
+ *   should be done by the implementation of close().
  *
  ****************************************************************************/
 
@@ -258,7 +256,6 @@ uint16_t can_datahandler(FAR struct can_conn_s *conn, FAR uint8_t *buffer,
  *
  ****************************************************************************/
 
-
 ssize_t can_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
                      int flags, FAR struct sockaddr *from,
                      FAR socklen_t *fromlen);
diff --git a/net/can/can_callback.c b/net/can/can_callback.c
index f8bff86..aab0e3e 100644
--- a/net/can/can_callback.c
+++ b/net/can/can_callback.c
@@ -119,15 +119,18 @@ uint16_t can_callback(FAR struct net_driver_s *dev,
   if (conn)
     {
 #ifdef CONFIG_NET_TIMESTAMP
-  /* TIMESTAMP sockopt is activated, create timestamp and copy to iob */
-	  if(conn->psock->s_timestamp)
-	    {
-		  struct timespec *ts = (struct timespec*)&dev->d_appdata[dev->d_len];
-		  struct timeval *tv = (struct timeval*)&dev->d_appdata[dev->d_len];
-		  dev->d_len += sizeof(struct timeval);
-		  clock_systimespec(ts);
-		  tv->tv_usec = ts->tv_nsec / 1000;
-	    }
+      /* TIMESTAMP sockopt is activated, create timestamp and copy to iob */
+
+      if (conn->psock->s_timestamp)
+        {
+          struct timespec *ts = (struct timespec *)
+                                                &dev->d_appdata[dev->d_len];
+          struct timeval *tv = (struct timeval *)
+                                                &dev->d_appdata[dev->d_len];
+          dev->d_len += sizeof(struct timeval);
+          clock_systimespec(ts);
+          tv->tv_usec = ts->tv_nsec / 1000;
+        }
 #endif
 
       /* Perform the callback */
diff --git a/net/can/can_conn.c b/net/can/can_conn.c
index 74f2d9b..574796c 100644
--- a/net/can/can_conn.c
+++ b/net/can/can_conn.c
@@ -138,9 +138,8 @@ FAR struct can_conn_s *can_alloc(void)
       /* Make sure that the connection is marked as uninitialized */
 
       memset(conn, 0, sizeof(*conn));
-      
+
       /* FIXME SocketCAN default behavior enables loopback */
-      
 
 #ifdef CONFIG_NET_CANPROTO_OPTIONS
       /* By default the filter is configured to catch all,
@@ -158,7 +157,6 @@ FAR struct can_conn_s *can_alloc(void)
       conn->filter_count = 1;
 #endif
 
-
       /* Enqueue the connection into the active list */
 
       dq_addlast(&conn->node, &g_active_can_connections);
@@ -172,8 +170,8 @@ FAR struct can_conn_s *can_alloc(void)
  * Name: can_free()
  *
  * Description:
- *   Free a NetLink connection structure that is no longer in use. This should
- *   be done by the implementation of close().
+ *   Free a NetLink connection structure that is no longer in use. This
+ *   should be done by the implementation of close().
  *
  ****************************************************************************/
 
diff --git a/net/can/can_getsockopt.c b/net/can/can_getsockopt.c
index e4149b6..238695c 100644
--- a/net/can/can_getsockopt.c
+++ b/net/can/can_getsockopt.c
@@ -98,7 +98,8 @@ int can_getsockopt(FAR struct socket *psock, int option,
           {
             ret = -EINVAL;
           }
-        else if (*value_len > CONFIG_NET_CAN_RAW_FILTER_MAX * sizeof(struct can_filter))
+        else if (*value_len > CONFIG_NET_CAN_RAW_FILTER_MAX *
+                   sizeof(struct can_filter))
           {
             ret = -EINVAL;
           }
@@ -106,19 +107,20 @@ int can_getsockopt(FAR struct socket *psock, int option,
           {
             int count = conn->filter_count;
 
-        	if (*value_len < count * sizeof(struct can_filter))
+          if (*value_len < count * sizeof(struct can_filter))
               {
                 count = *value_len / sizeof(struct can_filter);
               }
-        	else
-        	  {
-        	    *value_len = count * sizeof(struct can_filter);
-        	  }
+          else
+            {
+              *value_len = count * sizeof(struct can_filter);
+            }
 
-            for(int i = 0; i < count; i++)
+            for (int i = 0; i < count; i++)
               {
-            	((struct can_filter *)value)[i] = conn->filters[i];
+                ((struct can_filter *)value)[i] = conn->filters[i];
               }
+
             ret = OK;
           }
         break;
diff --git a/net/can/can_recvfrom.c b/net/can/can_recvfrom.c
index 98a0b2a..2211ed0 100644
--- a/net/can/can_recvfrom.c
+++ b/net/can/can_recvfrom.c
@@ -50,14 +50,13 @@
 #include <sys/time.h>
 #endif
 
-
 /****************************************************************************
  * Private Types
  ****************************************************************************/
 
 struct can_recvfrom_s
 {
-  FAR struct socket       *pr_sock;      /* The parent socket structure */
+  FAR struct socket *pr_sock;          /* The parent socket structure */
   FAR struct devif_callback_s *pr_cb;  /* Reference to callback instance */
   sem_t        pr_sem;                 /* Semaphore signals recv completion */
   size_t       pr_buflen;              /* Length of receive buffer */
@@ -233,14 +232,15 @@ static inline void can_newdata(FAR struct net_driver_s *dev,
 
 static inline int can_readahead(struct can_recvfrom_s *pstate)
 {
-  FAR struct can_conn_s *conn = (FAR struct can_conn_s *)pstate->pr_sock->s_conn;
+  FAR struct can_conn_s *conn =
+    (FAR struct can_conn_s *) pstate->pr_sock->s_conn;
   FAR struct iob_s *iob;
   int recvlen;
 
   /* Check there is any CAN data already buffered in a read-ahead
    * buffer.
    */
-  
+
   pstate->pr_recvlen = -1;
 
   if ((iob = iob_peek_queue(&conn->readahead)) != NULL &&
@@ -287,15 +287,16 @@ static inline int can_readahead(struct can_recvfrom_s *pstate)
                              IOBUSER_NET_CAN_READAHEAD);
         }
 
-	  /* do not pass frames with DLC > 8 to a legacy socket */
-	  if (!conn->fd_frames)
-	    {
-		  struct canfd_frame *cfd = (struct canfd_frame *)pstate->pr_buffer;
-		  if (cfd->len > CAN_MAX_DLEN)
-		    {
-	  			return 0;
-		    }
-	    }
+      /* do not pass frames with DLC > 8 to a legacy socket */
+
+      if (!conn->fd_frames)
+        {
+          struct canfd_frame *cfd = (struct canfd_frame *)pstate->pr_buffer;
+          if (cfd->len > CAN_MAX_DLEN)
+            {
+              return 0;
+            }
+        }
 
       return recvlen;
     }
@@ -319,13 +320,14 @@ static inline int can_readahead(struct can_recvfrom_s *pstate)
  *   The network is locked.
  *
  ****************************************************************************/
+
 #ifdef CONFIG_NET_TIMESTAMP
-static inline int can_readahead_timestamp(struct can_conn_s *conn, FAR uint8_t *buffer)
+static inline int can_readahead_timestamp(struct can_conn_s *conn,
+                                          FAR uint8_t *buffer)
 {
   FAR struct iob_s *iob;
   int recvlen;
 
-
   if ((iob = iob_peek_queue(&conn->readahead)) != NULL)
     {
       DEBUGASSERT(iob->io_pktlen > 0);
@@ -379,26 +381,27 @@ static inline int can_readahead_timestamp(struct can_conn_s *conn, FAR uint8_t *
 #ifdef CONFIG_NET_CANPROTO_OPTIONS
 static int can_recv_filter(struct can_conn_s *conn, canid_t id)
 {
-  for(int i = 0; i < conn->filter_count; i++)
+  for (int i = 0; i < conn->filter_count; i++)
     {
-	  if (conn->filters[i].can_id & CAN_INV_FILTER)
-	    {
-		  if((id & conn->filters[i].can_mask) !=
-				  ((conn->filters[i].can_id & ~CAN_INV_FILTER)
-						  & conn->filters[i].can_mask))
-		    {
-			  return 1;
-		    }
-	    }
-	  else
-	    {
-		  if((id & conn->filters[i].can_mask) ==
-				  (conn->filters[i].can_id & conn->filters[i].can_mask))
-		    {
-			  return 1;
-		    }
-	    }
+      if (conn->filters[i].can_id & CAN_INV_FILTER)
+        {
+          if ((id & conn->filters[i].can_mask) !=
+                ((conn->filters[i].can_id & ~CAN_INV_FILTER) &
+                conn->filters[i].can_mask))
+            {
+              return 1;
+            }
+        }
+      else
+        {
+          if ((id & conn->filters[i].can_mask) ==
+                (conn->filters[i].can_id & conn->filters[i].can_mask))
+            {
+              return 1;
+            }
+        }
     }
+
   return 0;
 }
 #endif
@@ -416,46 +419,50 @@ static uint16_t can_recvfrom_eventhandler(FAR struct net_driver_s *dev,
     {
       if ((flags & CAN_NEWDATA) != 0)
         {
-    	  /* If a new packet is available, check receive filters
-    	   * when is valid then complete the read action. */
+          /* If a new packet is available, check receive filters
+           * when is valid then complete the read action.
+           */
 #ifdef CONFIG_NET_CANPROTO_OPTIONS
-    	  if(can_recv_filter(conn,(canid_t)*dev->d_appdata) == 0)
-    	    {
-    		  flags &= ~CAN_NEWDATA;
-    	  	  return flags;
-    		}
+          if (can_recv_filter(conn, (canid_t) *dev->d_appdata) == 0)
+            {
+              flags &= ~CAN_NEWDATA;
+              return flags;
+            }
 #endif
 
-    	  /* do not pass frames with DLC > 8 to a legacy socket */
-    	  if (!conn->fd_frames)
-    	    {
-    		  struct canfd_frame *cfd = (struct canfd_frame*)dev->d_appdata;
-    	      if (cfd->len > CAN_MAX_DLEN)
-    	      {
-    	    	/* DO WE NEED TO CLEAR FLAGS?? */
-    	        flags &= ~CAN_NEWDATA;
-  	  			return flags;
-    	      }
-    	    }
+          /* do not pass frames with DLC > 8 to a legacy socket */
+
+          if (!conn->fd_frames)
+            {
+              struct canfd_frame *cfd = (struct canfd_frame *)dev->d_appdata;
+              if (cfd->len > CAN_MAX_DLEN)
+                {
+                  /* DO WE NEED TO CLEAR FLAGS?? */
+
+                  flags &= ~CAN_NEWDATA;
+                  return flags;
+                }
+            }
 
           /* Copy the packet */
 
           can_newdata(dev, pstate);
 
 #ifdef CONFIG_NET_TIMESTAMP
-		  if(pstate->pr_sock->s_timestamp)
-			{
-			  if(pstate->pr_msglen == sizeof(struct timeval))
-			    {
-				  can_readahead_timestamp(conn, pstate->pr_msgbuf);
-			    }
-			  else
-			    {
-				/* We still have to consume the data otherwise IOB gets full */
-				  uint8_t dummy_buf[sizeof(struct timeval)];
-				  can_readahead_timestamp(conn, &dummy_buf);
-			    }
-			}
+          if (pstate->pr_sock->s_timestamp)
+            {
+              if (pstate->pr_msglen == sizeof(struct timeval))
+                {
+                  can_readahead_timestamp(conn, pstate->pr_msgbuf);
+                }
+              else
+                {
+                  /* We still have to consume the data otherwise IOB gets full */
+
+                  uint8_t dummy_buf[sizeof(struct timeval)];
+                  can_readahead_timestamp(conn, &dummy_buf);
+                }
+            }
 #endif
 
           /* We are finished. */
@@ -508,6 +515,7 @@ static ssize_t can_recvfrom_result(int result,
   if (pstate->pr_result < 0)
     {
       /* This might return EAGAIN on a timeout */
+
       return pstate->pr_result;
     }
 
@@ -592,10 +600,10 @@ ssize_t can_recvfrom(FAR struct socket *psock, FAR void *buf,
 
   ret = can_readahead(&state);
   if (ret > 0)
-    {      
+    {
       goto errout_with_state;
     }
-    
+
   ret = state.pr_recvlen;
 
   /* Handle non-blocking CAN sockets */
@@ -610,7 +618,7 @@ ssize_t can_recvfrom(FAR struct socket *psock, FAR void *buf,
         {
           /* Nothing was received */
 
-          ret = -EAGAIN;          
+          ret = -EAGAIN;
           goto errout_with_state;
         }
     }
@@ -675,6 +683,7 @@ errout_with_state:
  *   flags    Receive flags (ignored)
  *
  ****************************************************************************/
+
 #ifdef CONFIG_NET_RECVMSG_CMSG
 ssize_t can_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg,
                     size_t len, int flags)
@@ -707,20 +716,22 @@ ssize_t can_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg,
   nxsem_init(&state.pr_sem, 0, 0); /* Doesn't really fail */
   nxsem_setprotocol(&state.pr_sem, SEM_PRIO_NONE);
 
-
   state.pr_buflen = msg->msg_iov->iov_len;
   state.pr_buffer = msg->msg_iov->iov_base;
+
 #ifdef CONFIG_NET_TIMESTAMP
-  if(psock->s_timestamp && msg->msg_controllen == (sizeof(struct cmsghdr) + sizeof(struct timeval)))
+  if (psock->s_timestamp && msg->msg_controllen ==
+        (sizeof(struct cmsghdr) + sizeof(struct timeval)))
     {
-	  struct cmsghdr* cmsg = CMSG_FIRSTHDR(msg);
-	  state.pr_msglen = sizeof(struct timeval);
-	  state.pr_msgbuf = CMSG_DATA(cmsg);
-	  cmsg->cmsg_level = SOL_SOCKET;
-	  cmsg->cmsg_type = SO_TIMESTAMP;
-	  cmsg->cmsg_len = state.pr_msglen;
+      struct cmsghdr *cmsg = CMSG_FIRSTHDR(msg);
+      state.pr_msglen = sizeof(struct timeval);
+      state.pr_msgbuf = CMSG_DATA(cmsg);
+      cmsg->cmsg_level = SOL_SOCKET;
+      cmsg->cmsg_type = SO_TIMESTAMP;
+      cmsg->cmsg_len = state.pr_msglen;
     }
 #endif
+
   state.pr_sock   = psock;
 
   /* Handle any any CAN data already buffered in a read-ahead buffer.  NOTE
@@ -732,20 +743,22 @@ ssize_t can_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg,
   if (ret > 0)
     {
 #ifdef CONFIG_NET_TIMESTAMP
-	  if(psock->s_timestamp)
-	    {
-		  if(state.pr_msglen == sizeof(struct timeval))
-		    {
-			  can_readahead_timestamp(conn, state.pr_msgbuf);
-		    }
-		  else
-		    {
-			/* We still have to consume the data otherwise IOB gets full */
-		    uint8_t dummy_buf[sizeof(struct timeval)];
-			can_readahead_timestamp(conn, &dummy_buf);
-		    }
-	    }
+      if (psock->s_timestamp)
+        {
+          if (state.pr_msglen == sizeof(struct timeval))
+            {
+              can_readahead_timestamp(conn, state.pr_msgbuf);
+            }
+          else
+            {
+              /* We still have to consume the data otherwise IOB gets full */
+
+              uint8_t dummy_buf[sizeof(struct timeval)];
+              can_readahead_timestamp(conn, &dummy_buf);
+            }
+        }
 #endif
+
       goto errout_with_state;
     }
 
diff --git a/net/can/can_send.c b/net/can/can_send.c
index be621b4..644adc3 100644
--- a/net/can/can_send.c
+++ b/net/can/can_send.c
@@ -118,8 +118,10 @@ static uint16_t psock_send_eventhandler(FAR struct net_driver_s *dev,
       else
         {
           /* Copy the packet data into the device packet buffer and send it */
-          //FIXME potentialy wrong function do we have a header??
-    	  devif_can_send(dev, pstate->snd_buffer, pstate->snd_buflen);
+
+          /* FIXME potentialy wrong function do we have a header?? */
+
+          devif_can_send(dev, pstate->snd_buffer, pstate->snd_buflen);
           pstate->snd_sent = pstate->snd_buflen;
         }
 
@@ -164,10 +166,10 @@ ssize_t psock_can_send(FAR struct socket *psock, FAR const void *buf,
                        size_t len)
 {
   FAR struct net_driver_s *dev;
-  FAR struct can_conn_s *conn; 
+  FAR struct can_conn_s *conn;
   struct send_s state;
   int ret = OK;
-  
+
   conn = (FAR struct can_conn_s *)psock->s_conn;
 
   /* Verify that the sockfd corresponds to valid, allocated socket */
@@ -184,20 +186,20 @@ ssize_t psock_can_send(FAR struct socket *psock, FAR const void *buf,
     {
       return -ENODEV;
     }
-    
-  if(conn->fd_frames)
+
+  if (conn->fd_frames)
     {
-        if(len != CANFD_MTU && len != CAN_MTU)
-          {
-              return -EINVAL;
-          } 
+      if (len != CANFD_MTU && len != CAN_MTU)
+        {
+          return -EINVAL;
+        }
     }
-    else 
+  else
     {
-        if(len != CAN_MTU)
-          {
-              return -EINVAL;
-          }
+      if (len != CAN_MTU)
+        {
+          return -EINVAL;
+        }
     }
 
   /* Perform the send operation */
@@ -236,8 +238,8 @@ ssize_t psock_can_send(FAR struct socket *psock, FAR const void *buf,
       netdev_txnotify_dev(dev);
 
       /* Wait for the send to complete or an error to occur.
-      * net_lockedwait will also terminate if a signal is received.
-      */
+       * net_lockedwait will also terminate if a signal is received.
+       */
 
       ret = net_lockedwait(&state.snd_sem);
 
diff --git a/net/can/can_setsockopt.c b/net/can/can_setsockopt.c
index 659d84b..6858c1a 100644
--- a/net/can/can_setsockopt.c
+++ b/net/can/can_setsockopt.c
@@ -88,29 +88,30 @@ int can_setsockopt(FAR struct socket *psock, int option,
   switch (option)
     {
       case CAN_RAW_FILTER:
-    	if (value_len == 0)
-    	  {
-    		conn->filter_count = 0;
-    	    ret = OK;
-    	  }
-    	else if (value_len % sizeof(struct can_filter) != 0)
+        if (value_len == 0)
+          {
+            conn->filter_count = 0;
+            ret = OK;
+          }
+        else if (value_len % sizeof(struct can_filter) != 0)
           {
             ret = -EINVAL;
           }
-        else if (value_len > CONFIG_NET_CAN_RAW_FILTER_MAX * sizeof(struct can_filter))
+        else if (value_len > CONFIG_NET_CAN_RAW_FILTER_MAX *
+                   sizeof(struct can_filter))
           {
             ret = -EINVAL;
           }
         else
           {
-		    count = value_len / sizeof(struct can_filter);
+        count = value_len / sizeof(struct can_filter);
 
-		    for(int i = 0; i < count; i++)
-		      {
-				conn->filters[i] = ((struct can_filter *)value)[i];
-		      }
+        for (int i = 0; i < count; i++)
+          {
+        conn->filters[i] = ((struct can_filter *)value)[i];
+          }
 
-		    conn->filter_count = count;
+        conn->filter_count = count;
 
             ret = OK;
           }
@@ -120,28 +121,28 @@ int can_setsockopt(FAR struct socket *psock, int option,
         break;
 
       case CAN_RAW_LOOPBACK:
-		if (value_len != sizeof(conn->loopback))
-			return -EINVAL;
+    if (value_len != sizeof(conn->loopback))
+      return -EINVAL;
 
-		conn->loopback = *(FAR int32_t *)value;
+    conn->loopback = *(FAR int32_t *)value;
 
-		break;
+    break;
 
       case CAN_RAW_RECV_OWN_MSGS:
-		if (value_len != sizeof(conn->recv_own_msgs))
-			return -EINVAL;
+    if (value_len != sizeof(conn->recv_own_msgs))
+      return -EINVAL;
 
-		conn->recv_own_msgs = *(FAR int32_t *)value;
+    conn->recv_own_msgs = *(FAR int32_t *)value;
 
-		break;
+    break;
 
       case CAN_RAW_FD_FRAMES:
-		if (value_len != sizeof(conn->fd_frames))
-			return -EINVAL;
+    if (value_len != sizeof(conn->fd_frames))
+      return -EINVAL;
 
-		conn->fd_frames = *(FAR int32_t *)value;
+    conn->fd_frames = *(FAR int32_t *)value;
 
-		break;
+    break;
 
       case CAN_RAW_JOIN_FILTERS:
         break;
diff --git a/net/can/can_sockif.c b/net/can/can_sockif.c
index 844ac3b..737788e 100644
--- a/net/can/can_sockif.c
+++ b/net/can/can_sockif.c
@@ -154,7 +154,8 @@ static uint16_t can_poll_eventhandler(FAR struct net_driver_s *dev,
 #if 0
       /* A poll is a sign that we are free to send data. */
 
-      else if ((flags & CAN_POLL) != 0 && psock_udp_cansend(info->psock) >= 0)
+      else if ((flags & CAN_POLL) != 0 &&
+                 psock_udp_cansend(info->psock) >= 0)
         {
           eventset |= (POLLOUT & info->fds->events);
         }
@@ -234,6 +235,7 @@ static int can_setup(FAR struct socket *psock, int protocol)
 
 #ifdef CONFIG_NET_TIMESTAMP
       /* Store psock in conn se we can read the SO_TIMESTAMP value */
+
       conn->psock = psock;
 #endif
 
@@ -486,7 +488,8 @@ static int can_listen(FAR struct socket *psock, int backlog)
  *   Perform a can connection
  *
  * Input Parameters:
- *   psock   A reference to the socket structure of the socket to be connected
+ *   psock   A reference to the socket structure of the socket
+ *           to be connected
  *   addr    The address of the remote server to connect to
  *   addrlen Length of address buffer
  *
@@ -615,8 +618,8 @@ static int can_poll_local(FAR struct socket *psock, FAR struct pollfd *fds,
       info->cb     = cb;
 
       /* Initialize the callback structure.  Save the reference to the info
-       * structure as callback private data so that it will be available during
-       * callback processing.
+       * structure as callback private data so that it will be available
+       * during callback processing.
        */
 
       cb->flags    = NETDEV_DOWN;
@@ -747,7 +750,8 @@ static ssize_t can_send(FAR struct socket *psock, FAR const void *buf,
  *   returned when the socket was not actually connected.
  *
  * Input Parameters:
- *   psock    A reference to the socket structure of the socket to be connected
+ *   psock    A reference to the socket structure of the socket
+ *            to be connected
  *   buf      Data to send
  *   len      Length of data to send
  *   flags    Send flags (ignored)


[incubator-nuttx] 29/31: NET_CAN_RAW_TX_DEADLINE use relative time with watchdog Instead of a polling timer, also every mailbox get its own watchdog and gets cancelled when a tx interrupt for the corresponding mailbox occurs.

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch SocketCAN
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 50643e37eaa540233f49854cf33ce3157c96da78
Author: Peter van der Perk <pe...@nxp.com>
AuthorDate: Wed Mar 18 11:33:53 2020 +0100

    NET_CAN_RAW_TX_DEADLINE use relative time with watchdog
    Instead of a polling timer, also every mailbox get its own watchdog
    and gets cancelled when a tx interrupt for the corresponding mailbox
    occurs.
---
 arch/arm/src/s32k1xx/s32k1xx_flexcan.c | 153 ++++++++++++++++-----------------
 net/can/Kconfig                        |   7 --
 2 files changed, 75 insertions(+), 85 deletions(-)

diff --git a/arch/arm/src/s32k1xx/s32k1xx_flexcan.c b/arch/arm/src/s32k1xx/s32k1xx_flexcan.c
index 0325033..b1005d7 100644
--- a/arch/arm/src/s32k1xx/s32k1xx_flexcan.c
+++ b/arch/arm/src/s32k1xx/s32k1xx_flexcan.c
@@ -142,7 +142,6 @@ static int peak_tx_mailbox_index_ = 0;
  */
 
 #define S32K1XX_WDDELAY     (1*CLK_TCK)
-#define S32K1XX_TXTIMEOUT   ((CONFIG_NET_CAN_RAW_TX_POLL/1000)*CLK_TCK)
 
 /****************************************************************************
  * Private Types
@@ -224,30 +223,30 @@ struct txmbstats
 
 struct s32k1xx_driver_s
 {
-  bool bifup;                  /* true:ifup false:ifdown */
-  uint8_t txtail;              /* The oldest busy TX descriptor */
-  uint8_t txhead;              /* The next TX descriptor to use */
-  uint8_t rxtail;              /* The next RX descriptor to use */
-  uint8_t phyaddr;             /* Selected PHY address */
+  bool bifup;                   /* true:ifup false:ifdown */
+  uint8_t txtail;               /* The oldest busy TX descriptor */
+  uint8_t txhead;               /* The next TX descriptor to use */
+  uint8_t rxtail;               /* The next RX descriptor to use */
+  uint8_t phyaddr;              /* Selected PHY address */
 #ifdef WORK_QUEUE
-  WDOG_ID txpoll;              /* TX poll timer */
+  WDOG_ID txpoll;               /* TX poll timer */
 #endif
 #ifdef TX_TIMEOUT_WQ
-  WDOG_ID txtimeout;           /* TX timeout timer */
+  WDOG_ID txtimeout[TXMBCOUNT]; /* TX timeout timer */
 #endif
-  struct work_s irqwork;       /* For deferring interrupt work to the work queue */
-  struct work_s pollwork;      /* For deferring poll work to the work queue */
+  struct work_s irqwork;        /* For deferring interrupt work to the wq */
+  struct work_s pollwork;       /* For deferring poll work to the work wq */
 #ifdef CAN_FD
-  struct canfd_frame *txdesc;  /* A pointer to the list of TX descriptor */
-  struct canfd_frame *rxdesc;  /* A pointer to the list of RX descriptors */
+  struct canfd_frame *txdesc;   /* A pointer to the list of TX descriptor */
+  struct canfd_frame *rxdesc;   /* A pointer to the list of RX descriptors */
 #else
-  struct can_frame *txdesc;    /* A pointer to the list of TX descriptor */
-  struct can_frame *rxdesc;    /* A pointer to the list of RX descriptors */
+  struct can_frame *txdesc;     /* A pointer to the list of TX descriptor */
+  struct can_frame *rxdesc;     /* A pointer to the list of RX descriptors */
 #endif
 
   /* This holds the information visible to the NuttX network */
 
-  struct net_driver_s dev;     /* Interface understood by the network */
+  struct net_driver_s dev;      /* Interface understood by the network */
 
   struct mb_s *rx;
   struct mb_s *tx;
@@ -311,10 +310,6 @@ static void s32k1xx_setenable(uint32_t enable);
 static void s32k1xx_setfreeze(uint32_t freeze);
 static uint32_t s32k1xx_waitmcr_change(uint32_t mask,
                                        uint32_t target_state);
-#ifdef TX_TIMEOUT_WQ
-static void s32k1xx_checkandaborttx(struct s32k1xx_driver_s *priv,
-        uint32_t mbi, struct timeval *now);
-#endif
 
 /* Interrupt handling */
 
@@ -446,31 +441,41 @@ static int s32k1xx_transmit(FAR struct s32k1xx_driver_s *priv)
     }
 
 #ifdef CONFIG_NET_CAN_RAW_TX_DEADLINE
-      if (priv->dev.d_sndlen > priv->dev.d_len)
+  int32_t timeout = 0;
+  struct timespec ts;
+  clock_systimespec(&ts);
+
+  if (priv->dev.d_sndlen > priv->dev.d_len)
+    {
+      struct timeval *tv =
+             (struct timeval *)(priv->dev.d_buf + priv->dev.d_len);
+      priv->txmb[mbi].deadline = *tv;
+      timeout  = (tv->tv_sec - ts.tv_sec)*CLK_TCK
+                 + ((tv->tv_usec - ts.tv_nsec / 1000)*CLK_TCK) / 1000000;
+      if (timeout < 0)
+        {
+          return 0;       /* No transmission for you! */
+        }
+    }
+  else
+    {
+      /* Default TX deadline defined in NET_CAN_RAW_DEFAULT_TX_DEADLINE */
+
+      if (CONFIG_NET_CAN_RAW_DEFAULT_TX_DEADLINE > 0)
         {
-          struct timeval *tv =
-                 (struct timeval *)(priv->dev.d_buf + priv->dev.d_len);
-          priv->txmb[mbi].deadline = *tv;
+          timeout = ((CONFIG_NET_CAN_RAW_DEFAULT_TX_DEADLINE / 1000000)
+              *CLK_TCK);
+          priv->txmb[mbi].deadline.tv_sec = ts.tv_sec +
+              CONFIG_NET_CAN_RAW_DEFAULT_TX_DEADLINE / 1000000;
+          priv->txmb[mbi].deadline.tv_usec = (ts.tv_nsec / 1000) +
+              CONFIG_NET_CAN_RAW_DEFAULT_TX_DEADLINE % 1000000;
         }
       else
         {
-          /* Default TX deadline defined in NET_CAN_RAW_DEFAULT_TX_DEADLINE */
-
-          if (CONFIG_NET_CAN_RAW_DEFAULT_TX_DEADLINE > 0)
-            {
-              struct timespec ts;
-              clock_systimespec(&ts);
-              priv->txmb[mbi].deadline.tv_sec = ts.tv_sec +
-                      CONFIG_NET_CAN_RAW_DEFAULT_TX_DEADLINE / 1000000;
-              priv->txmb[mbi].deadline.tv_usec = (ts.tv_nsec / 1000) +
-                      CONFIG_NET_CAN_RAW_DEFAULT_TX_DEADLINE % 1000000;
-            }
-          else
-            {
-              priv->txmb[mbi].deadline.tv_sec = 0;
-              priv->txmb[mbi].deadline.tv_usec = 0;
-            }
+          priv->txmb[mbi].deadline.tv_sec = 0;
+          priv->txmb[mbi].deadline.tv_usec = 0;
         }
+    }
 #endif
 
   peak_tx_mailbox_index_ =
@@ -580,10 +585,14 @@ static int s32k1xx_transmit(FAR struct s32k1xx_driver_s *priv)
 
   NETDEV_TXPACKETS(&priv->dev);
 
-  /* Setup the TX timeout watchdog (perhaps restarting the timer) */
 #ifdef TX_TIMEOUT_WQ
-  wd_start(priv->txtimeout, S32K1XX_TXTIMEOUT, s32k1xx_txtimeout_expiry, 1,
-           (wdparm_t)priv);
+  /* Setup the TX timeout watchdog (perhaps restarting the timer) */
+
+  if (timeout > 0)
+    {
+      wd_start(priv->txtimeout[mbi], timeout + 1, s32k1xx_txtimeout_expiry,
+                1, (wdparm_t)priv);
+    }
 #endif
 
   return OK;
@@ -838,19 +847,6 @@ static void s32k1xx_txdone(FAR struct s32k1xx_driver_s *priv, uint32_t flags)
 {
   #warning Missing logic
 
-#ifdef TX_TIMEOUT_WQ
-  /* We are here because a transmission completed, so the watchdog can be
-   * canceled.
-   */
-
-  wd_cancel(priv->txtimeout);
-
-  struct timespec ts;
-  struct timeval *now = (struct timeval *)&ts;
-  clock_systimespec(&ts);
-  now->tv_usec = ts.tv_nsec / 1000; /* timespec to timeval conversion */
-#endif
-
   /* FIXME First Process Error aborts */
 
   /* Process TX completions */
@@ -863,16 +859,14 @@ static void s32k1xx_txdone(FAR struct s32k1xx_driver_s *priv, uint32_t flags)
           putreg32(mb_bit, S32K1XX_CAN0_IFLAG1);
           flags &= ~mb_bit;
           NETDEV_TXDONE(&priv->dev);
-        }
-
 #ifdef TX_TIMEOUT_WQ
-      /* MB is not done, check for timeout */
+          /* We are here because a transmission completed, so the
+           * corresponding watchdog can be canceled.
+           */
 
-      else
-        {
-       s32k1xx_checkandaborttx(priv, mbi, now);
-        }
+          wd_cancel(priv->txtimeout[mbi]);
 #endif
+        }
 
       mb_bit <<= 1;
     }
@@ -1017,19 +1011,6 @@ static void s32k1xx_polltimer_expiry(int argc, uint32_t arg, ...)
  *
  ****************************************************************************/
 #ifdef TX_TIMEOUT_WQ
-static void s32k1xx_checkandaborttx(struct s32k1xx_driver_s *priv,
-  uint32_t mbi, struct timeval *now)
-{
-  if (priv->txmb[mbi].deadline.tv_sec != 0
-      && (now->tv_sec > priv->txmb[mbi].deadline.tv_sec
-      || now->tv_usec > priv->txmb[mbi].deadline.tv_usec))
-    {
-      NETDEV_TXTIMEOUTS(&priv->dev);
-      struct mb_s *mb = &priv->tx[mbi];
-      mb->cs.code = CAN_TXMB_ABORT;
-      priv->txmb[mbi].pending = TX_ABORT;
-    }
-}
 
 static void s32k1xx_txtimeout_work(FAR void *arg)
 {
@@ -1040,9 +1021,21 @@ static void s32k1xx_txtimeout_work(FAR void *arg)
   clock_systimespec(&ts);
   now->tv_usec = ts.tv_nsec / 1000; /* timespec to timeval conversion */
 
-  for (int i = 0; i < TXMBCOUNT; i++)
+  /* The watchdog timed out, yet we still check mailboxes in case the
+   * transmit function transmitted a new frame
+   */
+
+  for (int mbi = 0; mbi < TXMBCOUNT; mbi++)
     {
-      s32k1xx_checkandaborttx(priv, i, now);
+      if (priv->txmb[mbi].deadline.tv_sec != 0
+          && (now->tv_sec > priv->txmb[mbi].deadline.tv_sec
+          || now->tv_usec > priv->txmb[mbi].deadline.tv_usec))
+        {
+          NETDEV_TXTIMEOUTS(&priv->dev);
+          struct mb_s *mb = &priv->tx[mbi];
+          mb->cs.code = CAN_TXMB_ABORT;
+          priv->txmb[mbi].pending = TX_ABORT;
+        }
     }
 }
 
@@ -1637,7 +1630,11 @@ int s32k1xx_netinitialize(int intf)
   priv->txpoll        = wd_create();       /* Create periodic poll timer */
 #endif
 #ifdef TX_TIMEOUT_WQ
-  priv->txtimeout     = wd_create();       /* Create TX timeout timer */
+  for (int i = 0; i < TXMBCOUNT; i++)
+    {
+      priv->txtimeout[i] = wd_create();    /* Create TX timeout timer */
+    }
+
 #endif
   priv->rx            = (struct mb_s *)(S32K1XX_CAN0_MB);
   priv->tx            = (struct mb_s *)(S32K1XX_CAN0_MB +
diff --git a/net/can/Kconfig b/net/can/Kconfig
index 00bfabd..731a12b 100644
--- a/net/can/Kconfig
+++ b/net/can/Kconfig
@@ -51,13 +51,6 @@ config NET_CAN_RAW_TX_DEADLINE
 		CAN frame is still in the HW TX mailbox then the CAN driver will 
 		discard the CAN frame automatically.
 		
-config NET_CAN_RAW_TX_POLL
-	int "TX deadline polling rate (ms) "
-	default 500
-	depends on NET_CAN_RAW_TX_DEADLINE
-	---help---
-		The polling rate on which the CAN driver checks whenever a TX deadline occurs
-		
 config NET_CAN_RAW_DEFAULT_TX_DEADLINE
 	int "Default TX deadline when no deadline is given (us)"
 	default 0


[incubator-nuttx] 21/31: S32K1XX SocketCAN style fixes

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch SocketCAN
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 7d725c1c411ac43dfe97da7c8c857269df5f5dc8
Author: Jari van Ewijk <ja...@nxp.com>
AuthorDate: Fri Mar 13 12:29:56 2020 +0100

    S32K1XX SocketCAN style fixes
---
 arch/arm/src/s32k1xx/hardware/s32k1xx_flexcan.h |  49 ++--
 arch/arm/src/s32k1xx/s32k1xx_flexcan.c          | 362 +++++++++++++-----------
 arch/arm/src/s32k1xx/s32k1xx_flexcan.h          |   4 +-
 arch/arm/src/s32k1xx/s32k1xx_rtc.c              |  14 +-
 4 files changed, 224 insertions(+), 205 deletions(-)

diff --git a/arch/arm/src/s32k1xx/hardware/s32k1xx_flexcan.h b/arch/arm/src/s32k1xx/hardware/s32k1xx_flexcan.h
index 03d3d90..14f337b 100644
--- a/arch/arm/src/s32k1xx/hardware/s32k1xx_flexcan.h
+++ b/arch/arm/src/s32k1xx/hardware/s32k1xx_flexcan.h
@@ -70,7 +70,7 @@
 
 #define S32K1XX_CAN_MB_OFFSET         0x0080  /* CAN MB register */
 
-#define S32K1XX_CAN_RXIMR_OFFSET(n)   (0x0880 + ((n) << 2)) /* Rn Individual Mask Registers */
+#define S32K1XX_CAN_RXIMR_OFFSET(n)   (0x0880 + ((n) << 2))
 #  define S32K1XX_CAN_RXIMR0_OFFSET   0x0880  /* R0 Individual Mask Registers */
 #  define S32K1XX_CAN_RXIMR1_OFFSET   0x0884  /* R1 Individual Mask Registers */
 #  define S32K1XX_CAN_RXIMR2_OFFSET   0x0888  /* R2 Individual Mask Registers */
@@ -144,7 +144,7 @@
 
 #define S32K1XX_CAN_FDCTRL_OFFSET     0x0c00  /* CAN FD Control register */
 #define S32K1XX_CAN_FDCBT_OFFSET      0x0c04  /* CAN FD Bit Timing register */
-#define S32K1XX_CAN_FDCRC_OFFSET      0x0c08 /* CAN FD CRC register */
+#define S32K1XX_CAN_FDCRC_OFFSET      0x0c08  /* CAN FD CRC register */
 
 /* Register Addresses ***************************************************************************************/
 
@@ -343,11 +343,13 @@
 #define CAN_MCR_MAXMB_MASK            (0x7f << CAN_MCR_MAXMB_SHIFT)
                                                 /* Bit 7:  Reserved */
 #define CAN_MCR_IDAM_SHIFT            (8)       /* Bits 8-9: ID Acceptance Mode */
+
 #define CAN_MCR_IDAM_MASK             (3 << CAN_MCR_IDAM_SHIFT)
 #  define CAN_MCR_IDAM_FMTA           (0 << CAN_MCR_IDAM_SHIFT) /* Format A: One full ID  */
 #  define CAN_MCR_IDAM_FMTB           (1 << CAN_MCR_IDAM_SHIFT) /* Format B: Two full (or partial) IDs */
 #  define CAN_MCR_IDAM_FMTC           (2 << CAN_MCR_IDAM_SHIFT) /* Format C: Four partial IDs */
 #  define CAN_MCR_IDAM_FMTD           (3 << CAN_MCR_IDAM_SHIFT) /* Format D: All frames rejected */
+
                                                 /* Bit 10: Reserved */
 #define CAN_MCR_FDEN                  (1 << 11) /* Bit 11: CAN FD operation enable */
 #define CAN_MCR_AEN                   (1 << 12) /* Bit 12: Abort Enable */
@@ -386,13 +388,13 @@
 #define CAN_CTRL1_CLKSRC              (1 << 13) /* Bit 13: CAN Engine Clock Source */
 #define CAN_CTRL1_ERRMSK              (1 << 14) /* Bit 14: Error Mask */
 #define CAN_CTRL1_BOFFMSK             (1 << 15) /* Bit 15: Bus Off Mask */
-#define CAN_CTRL1_PSEG2_SHIFT         (16)       /* Bits 16-18: Phase Segment 2 */
+#define CAN_CTRL1_PSEG2_SHIFT         (16)      /* Bits 16-18: Phase Segment 2 */
 #define CAN_CTRL1_PSEG2_MASK          (7 << CAN_CTRL1_PSEG2_SHIFT)
-#define CAN_CTRL1_PSEG1_SHIFT         (19)       /* Bits 19-21: Phase Segment 1 */
+#define CAN_CTRL1_PSEG1_SHIFT         (19)      /* Bits 19-21: Phase Segment 1 */
 #define CAN_CTRL1_PSEG1_MASK          (7 << CAN_CTRL1_PSEG1_SHIFT)
-#define CAN_CTRL1_RJW_SHIFT           (22)       /* Bits 22-23: Resync Jump Width */
+#define CAN_CTRL1_RJW_SHIFT           (22)      /* Bits 22-23: Resync Jump Width */
 #define CAN_CTRL1_RJW_MASK            (3 << CAN_CTRL1_RJW_SHIFT)
-#define CAN_CTRL1_PRESDIV_SHIFT       (24)       /* Bits 24-31: Prescaler Division Factor */
+#define CAN_CTRL1_PRESDIV_SHIFT       (24)      /* Bits 24-31: Prescaler Division Factor */
 #define CAN_CTRL1_PRESDIV_MASK        (0xff << CAN_CTRL1_PRESDIV_SHIFT)
 
 /* Free Running Timer */
@@ -418,8 +420,8 @@
 #define CAN_ECR_TXERRCNT_SHIFT        (0)       /* Bits 0-7: Transmit Error Counter */
 #define CAN_ECR_TXERRCNT_MASK         (0xff << CAN_ECR_TXERRCNT_SHIFT)
 #define CAN_ECR_RXERRCNT_SHIFT        (8)       /* Bits 8-15: Receive Error Counter */
-#define CAN_ECR_RXERRCNT_MASK        (0xff << CAN_ECR_RXERRCNT_SHIFT)
-                                               /* Bits 16-31: Reserved */
+#define CAN_ECR_RXERRCNT_MASK         (0xff << CAN_ECR_RXERRCNT_SHIFT)
+                                                /* Bits 16-31: Reserved */
 
 /* Error and Status 1 Register */
 
@@ -428,13 +430,15 @@
 #define CAN_ESR1_BOFFINT              (1 << 2)  /* Bit 2:  'Bus Off' Interrupt */
 #define CAN_ESR1_RX                   (1 << 3)  /* Bit 3:  FlexCAN in Reception */
 #define CAN_ESR1_FLTCONF_SHIFT        (4)       /* Bits 4-5: Fault Confinement State */
+
 #define CAN_ESR1_FLTCONF_MASK         (3 << CAN_ESR1_FLTCONF_SHIFT)
 #  define CAN_ESR1_FLTCONF_ACTV       (0 << CAN_ESR1_FLTCONF_SHIFT) /* Error Active */
 #  define CAN_ESR1_FLTCONF_PASV       (1 << CAN_ESR1_FLTCONF_SHIFT) /* Error Passive */
 #  define CAN_ESR1_FLTCONF_OFF        (2 << CAN_ESR1_FLTCONF_SHIFT) /* Bus Off */
+
 #define CAN_ESR1_TX                   (1 << 6)  /* Bit 6:  FlexCAN in Transmission */
 #define CAN_ESR1_IDLE                 (1 << 7)  /* Bit 7:  CAN bus is in IDLE state */
-#define CAN_ESR1_RXWRN                  (1 << 8)  /* Bit 8:  Rx Error Warning */
+#define CAN_ESR1_RXWRN                (1 << 8)  /* Bit 8:  Rx Error Warning */
 #define CAN_ESR1_TXWRN                (1 << 9)  /* Bit 9:  TX Error Warning */
 #define CAN_ESR1_STFERR               (1 << 10) /* Bit 10: Stuffing Error */
 #define CAN_ESR1_FRMERR               (1 << 11) /* Bit 11: Form Error */
@@ -446,6 +450,7 @@
 #define CAN_ESR1_TWRNINT              (1 << 17) /* Bit 17: Tx Warning Interrupt Flag */
 #define CAN_ESR1_SYNCH                (1 << 18) /* Bit 18: CAN Synchronization Status */
                                                 /* Bits 19-31: Reserved */
+
 /* Interrupt Masks 2 Register */
 
 #define CAN_IMASK2(n)                 (1 << (n)) /* Bit n: Buffer MBn Mask */
@@ -463,6 +468,7 @@
 #define CAN_IFLAG1(n)                 (1 << (n)) /* Bit n: Buffer MBn Interrupt, n=0..4,8..31 */
 
 /* Control 2 Register */
+
                                                 /* Bits 0-10: Reserved */
 #define CAN_CTRL2_EDFLTDIS            (1 << 11) /* Bit 11:  Edge Filter Disable */
 #define CAN_CTRL2_ISOCANFDEN          (1 << 12) /* Bit 12:  ISO CAN FD Enable */
@@ -496,6 +502,7 @@
                                                 /* Bits 29-31: Reserved */
 
 /* Error and Status 2 Register */
+
                                                 /* Bits 0-12: Reserved */
 #define CAN_ESR2_IMB                  (1 << 13) /* Bit 13: Inactive Mailbox */
 #define CAN_ESR2_VPS                  (1 << 14) /* Bit 14: Valid Priority Status */
@@ -516,6 +523,7 @@
 /* Rx FIFO Global Mask Register (32 Rx FIFO Global Mask Bits) */
 
 /* Rx FIFO Information Register */
+
                                                 /* Bits 9-31: Reserved */
 #define CAN_RXFIR_IDHIT_SHIFT         (0)       /* Bits 0-8: Identifier Acceptance Filter Hit Indicator */
 #define CAN_RXFIR_IDHIT_MASK          (0x1ff << CAN_RXFIR_IDHIT_SHIFT)
@@ -531,12 +539,12 @@
 #define CAN_CBT_BTF                   (1 << 31) /* Bit 31: Bit Timing Format Enable */
 
 /* CAN MB TX codes */
-#define CAN_TXMB_INACTIVE             0x8       /* MB is not active.*/
-#define CAN_TXMB_ABORT                0x9       /* MB is aborted.*/
+#define CAN_TXMB_INACTIVE             0x8       /* MB is not active. */
+#define CAN_TXMB_ABORT                0x9       /* MB is aborted. */
 #define CAN_TXMB_DATAORREMOTE         0xC       /* MB is a TX Data Frame(when MB RTR = 0) or */
-                                                /* MB is a TX Remote Request Frame (when MB RTR = 1).*/
+                                                /* MB is a TX Remote Request Frame (when MB RTR = 1). */
 #define CAN_TXMB_TANSWER              0xE       /* MB is a TX Response Request Frame from */
-                                                /* an incoming Remote Request Frame.*/
+                                                /* an incoming Remote Request Frame. */
 #define CAN_TXMB_NOTUSED              0xF       /* Not used.*/
 
 /* CAN FD Control register (FDCTRL) */
@@ -558,12 +566,11 @@
 #define CAN_FDCRC_FD_TXCRC(x)         (((uint32_t)(((uint32_t)(x)) << 0))  & 0x1FFFFF)
 #define CAN_FDCRC_FD_MBCRC(x)         (((uint32_t)(((uint32_t)(x)) << 24)) & 0x7F000000)
 
-
 /* Rn Individual Mask Registers */
 
 #define CAN_RXIMR(n)                  (1 << (n)) /* Bit n: Individual Mask Bits */
 
- /* Pretended Networking Control 1 register */
+/* Pretended Networking Control 1 register */
 #define CAN_CTRL1_PN_
 
 /* Pretended Networking Control 2 register */
@@ -614,16 +621,4 @@
 /* CAN FD CRC register */
 #define CAN_FDCRC_
 
-/****************************************************************************************************
- * Public Types
- ****************************************************************************************************/
-
-/****************************************************************************************************
- * Public Data
- ****************************************************************************************************/
-
-/****************************************************************************************************
- * Public Functions
- ****************************************************************************************************/
-
 #endif /* __ARCH_ARM_SRC_S32K1XX_HARDWARE_S32K1XX_FLEXCAN_H */
diff --git a/arch/arm/src/s32k1xx/s32k1xx_flexcan.c b/arch/arm/src/s32k1xx/s32k1xx_flexcan.c
index 2654c2e..15e5b62 100644
--- a/arch/arm/src/s32k1xx/s32k1xx_flexcan.c
+++ b/arch/arm/src/s32k1xx/s32k1xx_flexcan.c
@@ -63,14 +63,17 @@
  * is required.
  */
 
-
 /* FIXME A workqueue is required for enet but for FLEXCAN it increased the
  * transmit latency by ~ 40us from 24 to 67us
  * Therefore for now its configurable by the WORK_QUEUE define
  * If we know for sure that a workqueue isn't required
- * Then all WORK_QUEUE related code will be removed */
+ * Then all WORK_QUEUE related code will be removed
+ */
+
 #if !defined(CONFIG_SCHED_WORKQUEUE)
-//#  error Work queue support is required
+
+/* #  error Work queue support is required */
+
 #else
 
   /* Select work queue.  Always use the LP work queue if available.  If not,
@@ -81,12 +84,14 @@
    * processing that never suspends.  Suspending the high priority work queue
    * may bring the system to its knees!
    */
-//#  define WORK_QUEUE
+
+/* #  define WORK_QUEUE */
+
 #  define CANWORK LPWORK
 #endif
 
-/* CONFIG_S32K1XX_FLEXCAN_NETHIFS determines the number of physical interfaces
- * that will be supported.
+/* CONFIG_S32K1XX_FLEXCAN_NETHIFS determines the number of physical
+ * interfaces that will be supported.
  */
 
 #define MASKSTDID                   0x000007ff
@@ -214,8 +219,8 @@ struct s32k1xx_driver_s
   struct canfd_frame *txdesc;  /* A pointer to the list of TX descriptor */
   struct canfd_frame *rxdesc;  /* A pointer to the list of RX descriptors */
 #else
-  struct can_frame *txdesc;  /* A pointer to the list of TX descriptor */
-  struct can_frame *rxdesc;  /* A pointer to the list of RX descriptors */
+  struct can_frame *txdesc;    /* A pointer to the list of TX descriptor */
+  struct can_frame *rxdesc;    /* A pointer to the list of RX descriptors */
 #endif
 
   /* This holds the information visible to the NuttX network */
@@ -242,7 +247,6 @@ static uint8_t g_rx_pool[sizeof(struct can_frame)*POOL_SIZE]
                __attribute__((aligned(ARMV7M_DCACHE_LINESIZE)));
 #endif
 
-
 /****************************************************************************
  * Private Function Prototypes
  ****************************************************************************/
@@ -284,8 +288,10 @@ static uint32_t s32k1xx_waitmcr_change(uint32_t mask,
 
 /* Interrupt handling */
 
-static void s32k1xx_receive(FAR struct s32k1xx_driver_s *priv, uint32_t flags);
-static void s32k1xx_txdone(FAR struct s32k1xx_driver_s *priv, uint32_t flags);
+static void s32k1xx_receive(FAR struct s32k1xx_driver_s *priv,
+                            uint32_t flags);
+static void s32k1xx_txdone(FAR struct s32k1xx_driver_s *priv,
+                           uint32_t flags);
 
 static int  s32k1xx_flexcan_interrupt(int irq, FAR void *context,
                                       FAR void *arg);
@@ -338,13 +344,15 @@ static bool s32k1xx_txringfull(FAR struct s32k1xx_driver_s *priv)
   uint32_t mbi = 0;
 
   while (mbi < TXMBCOUNT)
-	{
-	  if (priv->tx[mbi].cs.code != CAN_TXMB_DATAORREMOTE)
-		{
-		  return 0;
-		}
-	  mbi++;
-	}
+    {
+      if (priv->tx[mbi].cs.code != CAN_TXMB_DATAORREMOTE)
+        {
+          return 0;
+        }
+
+      mbi++;
+    }
+
   return 1;
 }
 
@@ -379,7 +387,7 @@ static int s32k1xx_transmit(FAR struct s32k1xx_driver_s *priv)
       (CAN_ESR2_IMB | CAN_ESR2_VPS))
     {
       mbi  = ((getreg32(S32K1XX_CAN0_ESR2) &
-    		CAN_ESR2_LPTM_MASK) >> CAN_ESR2_LPTM_SHIFT);
+        CAN_ESR2_LPTM_MASK) >> CAN_ESR2_LPTM_SHIFT);
       mbi -= RXMBCOUNT;
     }
 
@@ -411,98 +419,96 @@ static int s32k1xx_transmit(FAR struct s32k1xx_driver_s *priv)
   struct mb_s *mb = &priv->tx[mbi];
   mb->cs.code = CAN_TXMB_INACTIVE;
 
-  if(priv->dev.d_len == sizeof(struct can_frame))
+  if (priv->dev.d_len == sizeof(struct can_frame))
     {
-	  struct can_frame *frame = (struct can_frame *)priv->dev.d_buf;
-
-	  if (frame->can_id & CAN_EFF_FLAG)
-	    {
-	      cs.ide = 1;
-	      mb->id.ext = frame->can_id & MASKEXTID;
-	    }
-	  else
-	    {
-	      mb->id.std = frame->can_id & MASKSTDID;
-	    }
+      struct can_frame *frame = (struct can_frame *)priv->dev.d_buf;
 
-	#if 0
-	  cs.rtr = frame.isRemoteTransmissionRequest();
-	#endif
+      if (frame->can_id & CAN_EFF_FLAG)
+        {
+          cs.ide = 1;
+          mb->id.ext = frame->can_id & MASKEXTID;
+        }
+      else
+        {
+          mb->id.std = frame->can_id & MASKSTDID;
+        }
 
-	  cs.dlc = frame->can_dlc;
+  #if 0
+      /* cs.rtr = frame.isRemoteTransmissionRequest(); */
+  #endif
 
-	  mb->data[0].w00 = __builtin_bswap32(*(uint32_t*)&frame->data[0]);
-	  mb->data[1].w00 = __builtin_bswap32(*(uint32_t*)&frame->data[4]);
+      cs.dlc = frame->can_dlc;
 
+      mb->data[0].w00 = __builtin_bswap32(*(uint32_t *)&frame->data[0]);
+      mb->data[1].w00 = __builtin_bswap32(*(uint32_t *)&frame->data[4]);
     }
   else /* CAN FD frame */
     {
-  	  struct canfd_frame *frame = (struct canfd_frame *)priv->dev.d_buf;
-
-  	  cs.edl = 1; /* CAN FD Frame */
-
-  	  if (frame->can_id & CAN_EFF_FLAG)
-  	    {
-  	      cs.ide = 1;
-  	      mb->id.ext = frame->can_id & MASKEXTID;
-  	    }
-  	  else
-  	    {
-  	      mb->id.std = frame->can_id & MASKSTDID;
-  	    }
-
-  	#if 0
-  	  cs.rtr = frame.isRemoteTransmissionRequest();
-  	#endif
-
-  	  if(frame->len < 9)
-  	    {
-  		  cs.dlc = frame->len;
-  	    }
-  	  else
-  	    {
-  	      if (frame->len < 13)
-  	        {
-			  cs.dlc = 9;
-  	        }
-  	      else if (frame->len < 17)
-  	        {
-			   cs.dlc = 10;
-  	        }
-  	      else if (frame->len < 21)
-  	        {
-			   cs.dlc = 11;
-  	        }
-  	      else if (frame->len < 25)
-  	        {
-			   cs.dlc = 12;
-  	        }
-  	      else if (frame->len < 33)
-  	        {
-			   cs.dlc = 13;
-  	        }
-  	      else if (frame->len < 49)
-  	        {
-			   cs.dlc = 14;
-  	        }
-  	      else if (frame->len < 65)
-  	        {
-			   cs.dlc = 15;
-  	        }
-  	      else
-  	        {
-  	    	   cs.dlc = 15; /* FIXME check CAN FD spec */
-  	        }
-  	    }
-
-  	  uint32_t* frame_data_word = (uint32_t*)&frame->data[0];
-
-	  for(int i = 0; i < (frame->len + 4 - 1) / 4; i++)
-		{
-	  	  mb->data[i].w00 = __builtin_bswap32(frame_data_word[i]);
-		}
-    }
+      struct canfd_frame *frame = (struct canfd_frame *)priv->dev.d_buf;
+
+      cs.edl = 1; /* CAN FD Frame */
+
+      if (frame->can_id & CAN_EFF_FLAG)
+        {
+          cs.ide = 1;
+          mb->id.ext = frame->can_id & MASKEXTID;
+        }
+      else
+        {
+          mb->id.std = frame->can_id & MASKSTDID;
+        }
 
+#if 0
+      /* cs.rtr = frame.isRemoteTransmissionRequest(); */
+#endif
+
+      if (frame->len < 9)
+        {
+          cs.dlc = frame->len;
+        }
+      else
+        {
+          if (frame->len < 13)
+            {
+              cs.dlc = 9;
+            }
+          else if (frame->len < 17)
+            {
+              cs.dlc = 10;
+            }
+          else if (frame->len < 21)
+            {
+              cs.dlc = 11;
+            }
+          else if (frame->len < 25)
+            {
+              cs.dlc = 12;
+            }
+          else if (frame->len < 33)
+            {
+              cs.dlc = 13;
+            }
+          else if (frame->len < 49)
+            {
+              cs.dlc = 14;
+            }
+          else if (frame->len < 65)
+            {
+              cs.dlc = 15;
+            }
+          else
+            {
+              cs.dlc = 15; /* FIXME check CAN FD spec */
+            }
+        }
+
+      uint32_t *frame_data_word = (uint32_t *)&frame->data[0];
+
+      for (int i = 0; i < (frame->len + 4 - 1) / 4; i++)
+        {
+          mb->data[i].w00 = __builtin_bswap32(frame_data_word[i]);
+        }
+    }
 
   s32k1xx_gpiowrite(PIN_PORTD | PIN31, 0);
 
@@ -560,9 +566,13 @@ static int s32k1xx_txpoll(struct net_driver_s *dev)
 
           s32k1xx_transmit(priv);
 #if 0
-          //FIXME implement ring buffer and increment pointer just like the enet driver??
+          /* FIXME implement ring buffer and increment pointer just like the
+           * enet driver??
+           */
+
           priv->dev.d_buf =
-            (uint8_t *)s32k1xx_swap32((uint32_t)priv->txdesc[priv->txhead].data);
+            (uint8_t *)s32k1xx_swap32(
+              (uint32_t)priv->txdesc[priv->txhead].data);
 #endif
 
           /* Check if there is room in the device to hold another packet. If
@@ -583,7 +593,6 @@ static int s32k1xx_txpoll(struct net_driver_s *dev)
   return 0;
 }
 
-
 /****************************************************************************
  * Function: s32k1xx_receive
  *
@@ -601,15 +610,16 @@ static int s32k1xx_txpoll(struct net_driver_s *dev)
  *
  ****************************************************************************/
 
-static void s32k1xx_receive(FAR struct s32k1xx_driver_s *priv, uint32_t flags)
+static void s32k1xx_receive(FAR struct s32k1xx_driver_s *priv,
+                            uint32_t flags)
 {
   #warning Missing logic
   uint32_t regval;
 
   s32k1xx_gpiowrite(PIN_PORTD | PIN31, 1);
 
+  /* FIXME naive what if multiple flags are high?? */
 
-  //FIXME naive what if multiple flags are high??
   uint32_t mb_index = arm_clz(flags);
 
   if (mb_index)
@@ -618,9 +628,9 @@ static void s32k1xx_receive(FAR struct s32k1xx_driver_s *priv, uint32_t flags)
 
       /* Read the frame contents */
 
-      if(rf->cs.edl) /* CAN FD frame */
+      if (rf->cs.edl) /* CAN FD frame */
         {
-    	  struct canfd_frame* frame = priv->rxdesc;
+        struct canfd_frame *frame = priv->rxdesc;
 
           if (rf->cs.ide)
             {
@@ -637,49 +647,53 @@ static void s32k1xx_receive(FAR struct s32k1xx_driver_s *priv, uint32_t flags)
               frame->can_id |= FLAGRTR;
             }
 
-          if(rf->cs.dlc < 9){
+          if (rf->cs.dlc < 9)
+            {
               frame->len = rf->cs.dlc;
-          } else {
-        	  switch(rf->cs.dlc)
-        	    {
-        	     case 9:
-        	       frame->len = 12;
-        	       break;
-
-        	     case 10:
-        	       frame->len = 16;
-        	       break;
-
-        	     case 11:
-        	       frame->len = 20;
-        	       break;
-
-        	     case 12:
-        	       frame->len = 24;
-        	       break;
-
-        	     case 13:
-        	       frame->len = 32;
-        	       break;
-
-        	     case 14:
-        	       frame->len = 48;
-        	       break;
-
-        	     case 15:
-        	       frame->len = 64;
-        	       break;
-        	    }
-          }
-
-    	  uint32_t* frame_data_word = (uint32_t*)&frame->data[0];
-
-          for(int i = 0; i < (frame->len + 4 - 1) / 4; i++)
+            }
+          else
             {
-        	  frame_data_word[i] = __builtin_bswap32(rf->data[i].w00);
+              switch (rf->cs.dlc)
+                {
+                  case 9:
+                    frame->len = 12;
+                    break;
+
+                  case 10:
+                    frame->len = 16;
+                    break;
+
+                  case 11:
+                    frame->len = 20;
+                    break;
+
+                  case 12:
+                    frame->len = 24;
+                    break;
+
+                  case 13:
+                    frame->len = 32;
+                    break;
+
+                  case 14:
+                    frame->len = 48;
+                    break;
+
+                  case 15:
+                    frame->len = 64;
+                    break;
+                }
+            }
+
+          uint32_t *frame_data_word = (uint32_t *)&frame->data[0];
+
+          for (int i = 0; i < (frame->len + 4 - 1) / 4; i++)
+            {
+              frame_data_word[i] = __builtin_bswap32(rf->data[i].w00);
             }
 
           /* Clear MB interrupt flag */
+
           regval  = getreg32(S32K1XX_CAN0_IFLAG1);
           regval |= (0x80000000 >> mb_index);
           putreg32(regval, S32K1XX_CAN0_IFLAG1);
@@ -693,7 +707,7 @@ static void s32k1xx_receive(FAR struct s32k1xx_driver_s *priv, uint32_t flags)
         }
       else /* CAN 2.0 Frame */
         {
-    	  struct can_frame* frame = priv->rxdesc;
+        struct can_frame *frame = priv->rxdesc;
 
           if (rf->cs.ide)
             {
@@ -712,10 +726,11 @@ static void s32k1xx_receive(FAR struct s32k1xx_driver_s *priv, uint32_t flags)
 
           frame->can_dlc = rf->cs.dlc;
 
-    	  *(uint32_t*)&frame->data[0] = __builtin_bswap32(rf->data[0].w00);
-    	  *(uint32_t*)&frame->data[4] = __builtin_bswap32(rf->data[1].w00);
+          *(uint32_t *)&frame->data[0] = __builtin_bswap32(rf->data[0].w00);
+          *(uint32_t *)&frame->data[4] = __builtin_bswap32(rf->data[1].w00);
 
           /* Clear MB interrupt flag */
+
           regval  = getreg32(S32K1XX_CAN0_IFLAG1);
           regval |= (1 << mb_index);
           putreg32(regval, S32K1XX_CAN0_IFLAG1);
@@ -740,6 +755,7 @@ static void s32k1xx_receive(FAR struct s32k1xx_driver_s *priv, uint32_t flags)
        * to.  This is OK because devif_poll won't be called unless the
        * queue is not full.
        */
+
       priv->dev.d_buf = priv->txdesc;
     }
 }
@@ -785,9 +801,12 @@ static void s32k1xx_txdone(FAR struct s32k1xx_driver_s *priv, uint32_t flags)
         {
           putreg32(mb_bit, S32K1XX_CAN0_IFLAG1);
           flags &= ~mb_bit;
-#if 0 //FIXME TB ABORT SUPPORT
-          const bool txok = priv->tx[mbi].cs.code != CAN_TXMB_ABORT;
-          handleTxMailboxInterrupt(mbi, txok, utc_usec);
+#if 0 
+          /* FIXME TB ABORT SUPPORT */
+
+          /* const bool txok = priv->tx[mbi].cs.code != CAN_TXMB_ABORT;
+           * handleTxMailboxInterrupt(mbi, txok, utc_usec);
+           */
 #endif
 
           NETDEV_TXDONE(&priv->dev);
@@ -803,7 +822,6 @@ static void s32k1xx_txdone(FAR struct s32k1xx_driver_s *priv, uint32_t flags)
   devif_poll(&priv->dev, s32k1xx_txpoll);
 }
 
-
 /****************************************************************************
  * Function: s32k1xx_flexcan_interrupt
  *
@@ -824,7 +842,8 @@ static void s32k1xx_txdone(FAR struct s32k1xx_driver_s *priv, uint32_t flags)
  *
  ****************************************************************************/
 
-static int s32k1xx_flexcan_interrupt(int irq, FAR void *context, FAR void *arg)
+static int s32k1xx_flexcan_interrupt(int irq, FAR void *context,
+                                     FAR void *arg)
 {
   #warning Missing logic
   FAR struct s32k1xx_driver_s *priv = &g_flexcan[0];
@@ -1018,6 +1037,7 @@ static int s32k1xx_ifup(struct net_driver_s *dev)
 #ifdef WORK_QUEUE
 
   /* Set and activate a timer process */
+
   wd_start(priv->txpoll, S32K1XX_WDDELAY, s32k1xx_polltimer_expiry, 1,
            (wdparm_t)priv);
 #endif
@@ -1232,13 +1252,13 @@ static int s32k1xx_initialize(struct s32k1xx_driver_s *priv)
       return -1;
     }
 
+  /* Based on 80 MHz BUS clock calc through S32DS */
 
-  /* Based on 80Mhz BUS clock calc through S32DS */
   regval  = getreg32(S32K1XX_CAN0_CBT);
-  regval |= CAN_CBT_BTF |          /* Enable extended bit timing configurations
-                                    * for CAN-FD for setting up separately
-                                    * nominal and data phase */
-            CAN_CBT_EPRESDIV(3) |  /* Prescaler divisor factor of 3 */
+  regval |= CAN_CBT_BTF |         /* Enable extended bit timing
+                                   * configurations for CAN-FD for setting up
+                                   * separately nominal and data phase */
+            CAN_CBT_EPRESDIV(3) | /* Prescaler divisor factor of 3 */
             CAN_CBT_EPROPSEG(7) | /* Propagation segment of 7 time quantas */
             CAN_CBT_EPSEG1(6) |   /* Phase buffer segment 1 of 6 time quantas */
             CAN_CBT_EPSEG2(3) |   /* Phase buffer segment 2 of 3 time quantas */
@@ -1252,14 +1272,15 @@ static int s32k1xx_initialize(struct s32k1xx_driver_s *priv)
   regval |= CAN_MCR_FDEN;
   putreg32(regval, S32K1XX_CAN0_MCR);
 
-  /* Based on 80Mhz BUS clock calc through S32DS */
+  /* Based on 80 MHz BUS clock calc through S32DS */
+
   regval  = getreg32(S32K1XX_CAN0_FDCBT);
-  regval |= CAN_FDCBT_FPRESDIV(0) | /* Prescaler divisor factor of 1 */
-            CAN_FDCBT_FPROPSEG(15) | /* Propagation semgment of 7 time quantas
-                                     * (only register that doesn't add 1) */
-            CAN_FDCBT_FPSEG1(1) |   /* Phase buffer segment 1 of 7 time quantas */
-            CAN_FDCBT_FPSEG2(1) |   /* Phase buffer segment 2 of 5 time quantas */
-            CAN_FDCBT_FRJW(1);      /* Resynchorinzation jump width same as PSEG2 */
+  regval |= CAN_FDCBT_FPRESDIV(0) |  /* Prescaler divisor factor of 1 */
+            CAN_FDCBT_FPROPSEG(15) | /* Propagation segment of 7 time quantas
+                                      * (only register that doesn't add 1) */
+            CAN_FDCBT_FPSEG1(1) |    /* Phase buffer segment 1 of 7 time quantas */
+            CAN_FDCBT_FPSEG2(1) |    /* Phase buffer segment 2 of 5 time quantas */
+            CAN_FDCBT_FRJW(1);       /* Resynchorinzation jump width same as PSEG2 */
   putreg32(regval, S32K1XX_CAN0_FDCBT);
 
   /* Additional CAN-FD configurations */
@@ -1280,7 +1301,8 @@ static int s32k1xx_initialize(struct s32k1xx_driver_s *priv)
   for (i = TXMBCOUNT; i < TOTALMBCOUNT; i++)
     {
       priv->rx[i].id.w = 0x0;
-      //FIXME sometimes we get a hard fault here
+
+      /* FIXME sometimes we get a hard fault here */
     }
 
   putreg32(0x0, S32K1XX_CAN0_RXFGMASK);
@@ -1369,7 +1391,8 @@ static void s32k1xx_reset(struct s32k1xx_driver_s *priv)
   regval  = getreg32(S32K1XX_CAN0_MCR);
   regval |= CAN_MCR_SLFWAK | CAN_MCR_WRNEN | CAN_MCR_SRXDIS |
             CAN_MCR_IRMQ | CAN_MCR_AEN |
-            (((TOTALMBCOUNT - 1) << CAN_MCR_MAXMB_SHIFT) & CAN_MCR_MAXMB_MASK);
+            (((TOTALMBCOUNT - 1) << CAN_MCR_MAXMB_SHIFT) &
+            CAN_MCR_MAXMB_MASK);
   putreg32(regval, S32K1XX_CAN0_MCR);
 
   regval  = CAN_CTRL2_RRS | CAN_CTRL2_EACEN; /* FIXME TASD */
@@ -1474,6 +1497,7 @@ int s32k1xx_netinitialize(int intf)
 
 #ifdef WORK_QUEUE
   /* Create a watchdog for timing polling for and timing of transmissions */
+
   priv->txpoll        = wd_create();       /* Create periodic poll timer */
   priv->txtimeout     = wd_create();       /* Create TX timeout timer */
 #endif
diff --git a/arch/arm/src/s32k1xx/s32k1xx_flexcan.h b/arch/arm/src/s32k1xx/s32k1xx_flexcan.h
index 9dfe681..4568e0f 100644
--- a/arch/arm/src/s32k1xx/s32k1xx_flexcan.h
+++ b/arch/arm/src/s32k1xx/s32k1xx_flexcan.h
@@ -50,9 +50,8 @@
  * Pre-processor Definitions
  ************************************************************************************/
 
-
 /************************************************************************************
- * Public Functions
+ * Public Function Prototypes
  ************************************************************************************/
 
 #ifndef __ASSEMBLY__
@@ -106,7 +105,6 @@ void up_netinitialize(void);
  *
  ************************************************************************************/
 
-
 #undef EXTERN
 #if defined(__cplusplus)
 }
diff --git a/arch/arm/src/s32k1xx/s32k1xx_rtc.c b/arch/arm/src/s32k1xx/s32k1xx_rtc.c
index 7f84dcf..f407c8e 100644
--- a/arch/arm/src/s32k1xx/s32k1xx_rtc.c
+++ b/arch/arm/src/s32k1xx/s32k1xx_rtc.c
@@ -183,12 +183,14 @@ int up_rtc_initialize(void)
 
   regval  = getreg32(S32K1XX_RTC_SR);
 
-  if(regval & RTC_SR_TIF)
+  if (regval & RTC_SR_TIF)
     {
-	  regval &= ~RTC_SR_TCE;
-	  putreg32(regval, S32K1XX_RTC_SR);
+      regval &= ~RTC_SR_TCE;
+      putreg32(regval, S32K1XX_RTC_SR);
+
       /* Write TSR register to clear invalid */
-	  putreg32(0x0, S32K1XX_RTC_TSR);
+
+      putreg32(0x0, S32K1XX_RTC_TSR);
     }
 
   /* Enable the rtc */
@@ -295,11 +297,11 @@ int up_rtc_gettime(FAR struct timespec *tp)
 int up_rtc_settime(FAR const struct timespec *ts)
 {
   DEBUGASSERT(ts != NULL);
-  
+
   irqstate_t flags;
   uint32_t seconds;
   uint32_t prescaler;
-  
+
   seconds = ts->tv_sec;
   prescaler = ts->tv_nsec * (CONFIG_RTC_FREQUENCY / 1000000000);
 


[incubator-nuttx] 27/31: Implement NET_CAN_RAW_TX_DEADLINE in SocketCAN and S32K1XX FlexCAN driver

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch SocketCAN
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit e09f9e926d9b6828aaddb5df6905faff799b8f2c
Author: Peter van der Perk <pe...@nxp.com>
AuthorDate: Tue Mar 17 13:57:22 2020 +0100

    Implement NET_CAN_RAW_TX_DEADLINE in SocketCAN and S32K1XX FlexCAN driver
---
 arch/arm/src/s32k1xx/s32k1xx_flexcan.c | 195 ++++++++++++++++++++++++++++-----
 net/can/Kconfig                        |  19 ++++
 net/can/can.h                          |  24 ++++
 net/can/can_send.c                     | 158 +++++++++++++++++++++++++-
 net/can/can_sockif.c                   |   4 +-
 net/devif/devif_cansend.c              |   4 +-
 6 files changed, 372 insertions(+), 32 deletions(-)

diff --git a/arch/arm/src/s32k1xx/s32k1xx_flexcan.c b/arch/arm/src/s32k1xx/s32k1xx_flexcan.c
index 5c02aa0..0325033 100644
--- a/arch/arm/src/s32k1xx/s32k1xx_flexcan.c
+++ b/arch/arm/src/s32k1xx/s32k1xx_flexcan.c
@@ -49,7 +49,7 @@
 #include "s32k1xx_pin.h"
 #include "s32k1xx_flexcan.h"
 
-#ifdef CONFIG_NET_TIMESTAMP
+#ifdef CONFIG_NET_CMSG
 #include <sys/time.h>
 #endif
 
@@ -117,24 +117,32 @@
 
 #define POOL_SIZE                   1
 
-#ifdef CONFIG_NET_TIMESTAMP
+#ifdef CONFIG_NET_CMSG
 #define MSG_DATA                    sizeof(struct timeval)
 #else
 #define MSG_DATA                    0
 #endif
 
+#ifdef CONFIG_NET_CAN_RAW_TX_DEADLINE
+
+#  if !defined(CONFIG_SCHED_WORKQUEUE)
+#    error Work queue support is required
+#  endif
+
+#define TX_TIMEOUT_WQ
+#endif
+
 /* Interrupt flags for RX fifo */
 #define IFLAG1_RXFIFO               (CAN_FIFO_NE | CAN_FIFO_WARN | CAN_FIFO_OV)
 
 static int peak_tx_mailbox_index_ = 0;
 
-#ifdef WORK_QUEUE
 /* TX poll delay = 1 seconds. CLK_TCK is the number of clock ticks per
  * second.
  */
 
 #define S32K1XX_WDDELAY     (1*CLK_TCK)
-#endif
+#define S32K1XX_TXTIMEOUT   ((CONFIG_NET_CAN_RAW_TX_POLL/1000)*CLK_TCK)
 
 /****************************************************************************
  * Private Types
@@ -198,6 +206,18 @@ struct mb_s
 #endif
 };
 
+#ifdef CONFIG_NET_CAN_RAW_TX_DEADLINE
+#define TX_ABORT -1
+#define TX_FREE 0
+#define TX_BUSY 1
+
+struct txmbstats
+{
+  struct timeval deadline;
+  uint32_t pending; /* -1 = abort, 0 = free, 1 = busy  */
+};
+#endif
+
 /* The s32k1xx_driver_s encapsulates all state information for a single
  * hardware interface
  */
@@ -211,6 +231,8 @@ struct s32k1xx_driver_s
   uint8_t phyaddr;             /* Selected PHY address */
 #ifdef WORK_QUEUE
   WDOG_ID txpoll;              /* TX poll timer */
+#endif
+#ifdef TX_TIMEOUT_WQ
   WDOG_ID txtimeout;           /* TX timeout timer */
 #endif
   struct work_s irqwork;       /* For deferring interrupt work to the work queue */
@@ -229,6 +251,10 @@ struct s32k1xx_driver_s
 
   struct mb_s *rx;
   struct mb_s *tx;
+
+#ifdef CONFIG_NET_CAN_RAW_TX_DEADLINE
+  struct txmbstats txmb[TXMBCOUNT];
+#endif
 };
 
 /****************************************************************************
@@ -285,6 +311,10 @@ static void s32k1xx_setenable(uint32_t enable);
 static void s32k1xx_setfreeze(uint32_t freeze);
 static uint32_t s32k1xx_waitmcr_change(uint32_t mask,
                                        uint32_t target_state);
+#ifdef TX_TIMEOUT_WQ
+static void s32k1xx_checkandaborttx(struct s32k1xx_driver_s *priv,
+        uint32_t mbi, struct timeval *now);
+#endif
 
 /* Interrupt handling */
 
@@ -301,6 +331,10 @@ static int  s32k1xx_flexcan_interrupt(int irq, FAR void *context,
 static void s32k1xx_poll_work(FAR void *arg);
 static void s32k1xx_polltimer_expiry(int argc, uint32_t arg, ...);
 #endif
+#ifdef TX_TIMEOUT_WQ
+static void s32k1xx_txtimeout_work(FAR void *arg);
+static void s32k1xx_txtimeout_expiry(int argc, uint32_t arg, ...);
+#endif
 
 /* NuttX callback functions */
 
@@ -411,6 +445,34 @@ static int s32k1xx_transmit(FAR struct s32k1xx_driver_s *priv)
       return 0;       /* No transmission for you! */
     }
 
+#ifdef CONFIG_NET_CAN_RAW_TX_DEADLINE
+      if (priv->dev.d_sndlen > priv->dev.d_len)
+        {
+          struct timeval *tv =
+                 (struct timeval *)(priv->dev.d_buf + priv->dev.d_len);
+          priv->txmb[mbi].deadline = *tv;
+        }
+      else
+        {
+          /* Default TX deadline defined in NET_CAN_RAW_DEFAULT_TX_DEADLINE */
+
+          if (CONFIG_NET_CAN_RAW_DEFAULT_TX_DEADLINE > 0)
+            {
+              struct timespec ts;
+              clock_systimespec(&ts);
+              priv->txmb[mbi].deadline.tv_sec = ts.tv_sec +
+                      CONFIG_NET_CAN_RAW_DEFAULT_TX_DEADLINE / 1000000;
+              priv->txmb[mbi].deadline.tv_usec = (ts.tv_nsec / 1000) +
+                      CONFIG_NET_CAN_RAW_DEFAULT_TX_DEADLINE % 1000000;
+            }
+          else
+            {
+              priv->txmb[mbi].deadline.tv_sec = 0;
+              priv->txmb[mbi].deadline.tv_usec = 0;
+            }
+        }
+#endif
+
   peak_tx_mailbox_index_ =
     (peak_tx_mailbox_index_ > mbi ? peak_tx_mailbox_index_ : mbi);
 
@@ -514,6 +576,16 @@ static int s32k1xx_transmit(FAR struct s32k1xx_driver_s *priv)
   regval |= mb_bit;
   putreg32(regval, S32K1XX_CAN0_IMASK1);
 
+  /* Increment statistics */
+
+  NETDEV_TXPACKETS(&priv->dev);
+
+  /* Setup the TX timeout watchdog (perhaps restarting the timer) */
+#ifdef TX_TIMEOUT_WQ
+  wd_start(priv->txtimeout, S32K1XX_TXTIMEOUT, s32k1xx_txtimeout_expiry, 1,
+           (wdparm_t)priv);
+#endif
+
   return OK;
 }
 
@@ -544,8 +616,6 @@ static int s32k1xx_transmit(FAR struct s32k1xx_driver_s *priv)
 
 static int s32k1xx_txpoll(struct net_driver_s *dev)
 {
-  #warning Missing logic
-
   FAR struct s32k1xx_driver_s *priv =
     (FAR struct s32k1xx_driver_s *)dev->d_private;
 
@@ -560,15 +630,6 @@ static int s32k1xx_txpoll(struct net_driver_s *dev)
           /* Send the packet */
 
           s32k1xx_transmit(priv);
-#if 0
-          /* FIXME implement ring buffer and increment pointer just like the
-           * enet driver??
-           */
-
-          priv->dev.d_buf =
-            (uint8_t *)s32k1xx_swap32(
-              (uint32_t)priv->txdesc[priv->txhead].data);
-#endif
 
           /* Check if there is room in the device to hold another packet. If
            * not, return a non-zero value to terminate the poll.
@@ -777,15 +838,20 @@ static void s32k1xx_txdone(FAR struct s32k1xx_driver_s *priv, uint32_t flags)
 {
   #warning Missing logic
 
+#ifdef TX_TIMEOUT_WQ
   /* We are here because a transmission completed, so the watchdog can be
    * canceled.
    */
 
-#ifdef WORK_QUEUE
   wd_cancel(priv->txtimeout);
+
+  struct timespec ts;
+  struct timeval *now = (struct timeval *)&ts;
+  clock_systimespec(&ts);
+  now->tv_usec = ts.tv_nsec / 1000; /* timespec to timeval conversion */
 #endif
 
-  /* FIXME process aborts */
+  /* FIXME First Process Error aborts */
 
   /* Process TX completions */
 
@@ -796,16 +862,17 @@ static void s32k1xx_txdone(FAR struct s32k1xx_driver_s *priv, uint32_t flags)
         {
           putreg32(mb_bit, S32K1XX_CAN0_IFLAG1);
           flags &= ~mb_bit;
-#if 0 
-          /* FIXME TB ABORT SUPPORT */
+          NETDEV_TXDONE(&priv->dev);
+        }
 
-          /* const bool txok = priv->tx[mbi].cs.code != CAN_TXMB_ABORT;
-           * handleTxMailboxInterrupt(mbi, txok, utc_usec);
-           */
-#endif
+#ifdef TX_TIMEOUT_WQ
+      /* MB is not done, check for timeout */
 
-          NETDEV_TXDONE(&priv->dev);
+      else
+        {
+       s32k1xx_checkandaborttx(priv, mbi, now);
         }
+#endif
 
       mb_bit <<= 1;
     }
@@ -904,7 +971,6 @@ static void s32k1xx_poll_work(FAR void *arg)
            1, (wdparm_t)priv);
   net_unlock();
 }
-#endif
 
 /****************************************************************************
  * Function: s32k1xx_polltimer_expiry
@@ -924,7 +990,6 @@ static void s32k1xx_poll_work(FAR void *arg)
  *
  ****************************************************************************/
 
-#ifdef WORK_QUEUE
 static void s32k1xx_polltimer_expiry(int argc, uint32_t arg, ...)
 {
   #warning Missing logic
@@ -936,6 +1001,82 @@ static void s32k1xx_polltimer_expiry(int argc, uint32_t arg, ...)
 }
 #endif
 
+/****************************************************************************
+ * Function: s32k1xx_txtimeout_work
+ *
+ * Description:
+ *   Perform TX timeout related work from the worker thread
+ *
+ * Input Parameters:
+ *   arg - The argument passed when work_queue() as called.
+ *
+ * Returned Value:
+ *   OK on success
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+#ifdef TX_TIMEOUT_WQ
+static void s32k1xx_checkandaborttx(struct s32k1xx_driver_s *priv,
+  uint32_t mbi, struct timeval *now)
+{
+  if (priv->txmb[mbi].deadline.tv_sec != 0
+      && (now->tv_sec > priv->txmb[mbi].deadline.tv_sec
+      || now->tv_usec > priv->txmb[mbi].deadline.tv_usec))
+    {
+      NETDEV_TXTIMEOUTS(&priv->dev);
+      struct mb_s *mb = &priv->tx[mbi];
+      mb->cs.code = CAN_TXMB_ABORT;
+      priv->txmb[mbi].pending = TX_ABORT;
+    }
+}
+
+static void s32k1xx_txtimeout_work(FAR void *arg)
+{
+  FAR struct s32k1xx_driver_s *priv = (FAR struct s32k1xx_driver_s *)arg;
+
+  struct timespec ts;
+  struct timeval *now = (struct timeval *)&ts;
+  clock_systimespec(&ts);
+  now->tv_usec = ts.tv_nsec / 1000; /* timespec to timeval conversion */
+
+  for (int i = 0; i < TXMBCOUNT; i++)
+    {
+      s32k1xx_checkandaborttx(priv, i, now);
+    }
+}
+
+/****************************************************************************
+ * Function: s32k1xx_txtimeout_expiry
+ *
+ * Description:
+ *   Our TX watchdog timed out.  Called from the timer interrupt handler.
+ *   The last TX never completed.  Reset the hardware and start again.
+ *
+ * Input Parameters:
+ *   argc - The number of available arguments
+ *   arg  - The first argument
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *   Global interrupts are disabled by the watchdog logic.
+ *
+ ****************************************************************************/
+
+static void s32k1xx_txtimeout_expiry(int argc, uint32_t arg, ...)
+{
+  FAR struct s32k1xx_driver_s *priv = (FAR struct s32k1xx_driver_s *)arg;
+
+  /* Schedule to perform the TX timeout processing on the worker thread
+   */
+
+  work_queue(CANWORK, &priv->irqwork, s32k1xx_txtimeout_work, priv, 0);
+}
+
+#endif
+
 static void s32k1xx_setenable(uint32_t enable)
 {
   uint32_t regval;
@@ -1494,6 +1635,8 @@ int s32k1xx_netinitialize(int intf)
   /* Create a watchdog for timing polling for and timing of transmissions */
 
   priv->txpoll        = wd_create();       /* Create periodic poll timer */
+#endif
+#ifdef TX_TIMEOUT_WQ
   priv->txtimeout     = wd_create();       /* Create TX timeout timer */
 #endif
   priv->rx            = (struct mb_s *)(S32K1XX_CAN0_MB);
diff --git a/net/can/Kconfig b/net/can/Kconfig
index ac94021..00bfabd 100644
--- a/net/can/Kconfig
+++ b/net/can/Kconfig
@@ -51,6 +51,25 @@ config NET_CAN_RAW_TX_DEADLINE
 		CAN frame is still in the HW TX mailbox then the CAN driver will 
 		discard the CAN frame automatically.
 		
+config NET_CAN_RAW_TX_POLL
+	int "TX deadline polling rate (ms) "
+	default 500
+	depends on NET_CAN_RAW_TX_DEADLINE
+	---help---
+		The polling rate on which the CAN driver checks whenever a TX deadline occurs
+		
+config NET_CAN_RAW_DEFAULT_TX_DEADLINE
+	int "Default TX deadline when no deadline is given (us)"
+	default 0
+	depends on NET_CAN_RAW_TX_DEADLINE
+	---help---
+		Some applications may not use the NET_CAN_RAW_TX_DEADLINE flag.
+		By default their deadline becomes 0 which means it becomes infinite.
+		This would mean that packets from applications without the 
+		NET_CAN_RAW_TX_DEADLINE flag, can block the TX mailboxes forever.
+		This config can set the default deadline when no deadline has been 
+		given.
+		
 config NET_CAN_RAW_FILTER_MAX
 	int "CAN_RAW_FILTER max filter count"
 	default 32
diff --git a/net/can/can.h b/net/can/can.h
index 00c297d..a727612 100644
--- a/net/can/can.h
+++ b/net/can/can.h
@@ -331,6 +331,30 @@ ssize_t psock_can_send(FAR struct socket *psock, FAR const void *buf,
                        size_t len);
 
 /****************************************************************************
+ * Name: psock_can_sendmsg
+ *
+ * Description:
+ *   The psock_can_sendmsg() call may be used only when the packet socket is
+ *   in a connected state (so that the intended recipient is known).
+ *
+ * Input Parameters:
+ *   psock    An instance of the internal socket structure.
+ *   msg      msg to send
+ *   len      Length of msg to send
+ *
+ * Returned Value:
+ *   On success, returns the number of characters sent.  On  error,
+ *   a negated errno value is returned.  See send() for the complete list
+ *   of return values.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_CMSG
+ssize_t psock_can_sendmsg(FAR struct socket *psock, FAR struct msghdr *msg,
+                       size_t len);
+#endif
+
+/****************************************************************************
  * Name: can_readahead_signal
  *
  * Description:
diff --git a/net/can/can_send.c b/net/can/can_send.c
index dfb03d0..ddfa83f 100644
--- a/net/can/can_send.c
+++ b/net/can/can_send.c
@@ -61,6 +61,10 @@
 #include "socket/socket.h"
 #include "can/can.h"
 
+#ifdef CONFIG_NET_CMSG
+#include <sys/time.h>
+#endif
+
 /****************************************************************************
  * Private Types
  ****************************************************************************/
@@ -123,10 +127,15 @@ static uint16_t psock_send_eventhandler(FAR struct net_driver_s *dev,
         {
           /* Copy the packet data into the device packet buffer and send it */
 
-          /* FIXME potentialy wrong function do we have a header?? */
-
           devif_can_send(dev, pstate->snd_buffer, pstate->snd_buflen);
           pstate->snd_sent = pstate->snd_buflen;
+
+          if (pstate->pr_msglen > 0) /* concat cmsg data after packet */
+            {
+              memcpy(dev->d_buf + pstate->snd_buflen, pstate->pr_msgbuf,
+                      pstate->pr_msglen);
+              dev->d_sndlen = pstate->snd_buflen + pstate->pr_msglen;
+            }
         }
 
       /* Don't allow any further call backs. */
@@ -279,4 +288,149 @@ ssize_t psock_can_send(FAR struct socket *psock, FAR const void *buf,
   return state.snd_sent;
 }
 
+/****************************************************************************
+ * Name: psock_can_sendmsg
+ *
+ * Description:
+ *   The psock_can_sendmsg() call may be used only when the packet socket is
+ *   in a connected state (so that the intended recipient is known).
+ *
+ * Input Parameters:
+ *   psock    An instance of the internal socket structure.
+ *   msg      msg to send
+ *   len      Length of msg to send
+ *
+ * Returned Value:
+ *   On success, returns the number of characters sent.  On  error,
+ *   a negated errno value is retruend.  See send() for the complete list
+ *   of return values.
+ *
+ ****************************************************************************/
+
+ssize_t psock_can_sendmsg(FAR struct socket *psock, FAR struct msghdr *msg,
+                       size_t len)
+{
+  FAR struct net_driver_s *dev;
+  FAR struct can_conn_s *conn;
+  struct send_s state;
+  int ret = OK;
+
+  conn = (FAR struct can_conn_s *)psock->s_conn;
+
+  /* Verify that the sockfd corresponds to valid, allocated socket */
+
+  if (!psock || psock->s_crefs <= 0)
+    {
+      return -EBADF;
+    }
+
+  /* Get the device driver that will service this transfer */
+
+  dev = conn->dev;
+  if (dev == NULL)
+    {
+      return -ENODEV;
+    }
+
+  if (conn->fd_frames)
+    {
+      if (msg->msg_iov->iov_len != CANFD_MTU
+              && msg->msg_iov->iov_len != CAN_MTU)
+        {
+          return -EINVAL;
+        }
+    }
+  else
+    {
+      if (msg->msg_iov->iov_len != CAN_MTU)
+        {
+          return -EINVAL;
+        }
+    }
+
+  /* Perform the send operation */
+
+  /* Initialize the state structure. This is done with the network locked
+   * because we don't want anything to happen until we are ready.
+   */
+
+  net_lock();
+  memset(&state, 0, sizeof(struct send_s));
+
+  /* This semaphore is used for signaling and, hence, should not have
+   * priority inheritance enabled.
+   */
+
+  nxsem_init(&state.snd_sem, 0, 0); /* Doesn't really fail */
+  nxsem_setprotocol(&state.snd_sem, SEM_PRIO_NONE);
+
+  state.snd_sock      = psock;                  /* Socket descriptor */
+  state.snd_buflen    = msg->msg_iov->iov_len;  /* bytes to send */
+  state.snd_buffer    = msg->msg_iov->iov_base; /* Buffer to send from */
+
+  if (msg->msg_controllen > sizeof(struct cmsghdr))
+    {
+      struct cmsghdr *cmsg = CMSG_FIRSTHDR(msg);
+      if (conn->tx_deadline && cmsg->cmsg_level == SOL_CAN_RAW
+              && cmsg->cmsg_type == CAN_RAW_TX_DEADLINE
+              && cmsg->cmsg_len == sizeof(struct timeval))
+        {
+          state.pr_msgbuf     = CMSG_DATA(cmsg); /* Buffer to cmsg data */
+          state.pr_msglen     = cmsg->cmsg_len;  /* len of cmsg data */
+        }
+    }
+
+  /* Allocate resource to receive a callback */
+
+  state.snd_cb = can_callback_alloc(dev, conn);
+  if (state.snd_cb)
+    {
+      /* Set up the callback in the connection */
+
+      state.snd_cb->flags = CAN_POLL;
+      state.snd_cb->priv  = (FAR void *)&state;
+      state.snd_cb->event = psock_send_eventhandler;
+
+      /* Notify the device driver that new TX data is available. */
+
+      netdev_txnotify_dev(dev);
+
+      /* Wait for the send to complete or an error to occur.
+       * net_lockedwait will also terminate if a signal is received.
+       */
+
+      ret = net_lockedwait(&state.snd_sem);
+
+      /* Make sure that no further events are processed */
+
+      can_callback_free(dev, conn, state.snd_cb);
+    }
+
+  nxsem_destroy(&state.snd_sem);
+  net_unlock();
+
+  /* Check for a errors, Errors are signalled by negative errno values
+   * for the send length
+   */
+
+  if (state.snd_sent < 0)
+    {
+      return state.snd_sent;
+    }
+
+  /* If net_lockedwait failed, then we were probably reawakened by a signal.
+   * In this case, net_lockedwait will have returned negated errno
+   * appropriately.
+   */
+
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  /* Return the number of bytes actually sent */
+
+  return state.snd_sent;
+}
+
 #endif /* CONFIG_NET && CONFIG_NET_CAN */
diff --git a/net/can/can_sockif.c b/net/can/can_sockif.c
index 09a61d0..497f74b 100644
--- a/net/can/can_sockif.c
+++ b/net/can/can_sockif.c
@@ -797,7 +797,7 @@ static ssize_t can_sendto(FAR struct socket *psock, FAR const void *buf,
  ****************************************************************************/
 #ifdef CONFIG_NET_CMSG
 static ssize_t can_sendmsg(FAR struct socket *psock, FAR struct msghdr *msg,
-                    size_t len, int flags);
+                    size_t len, int flags)
 {
   ssize_t ret;
 
@@ -807,7 +807,7 @@ static ssize_t can_sendmsg(FAR struct socket *psock, FAR struct msghdr *msg,
     {
       /* Raw packet send */
 
-      ret = psock_can_send(psock, buf, len);
+      ret = psock_can_sendmsg(psock, msg, len);
     }
   else
     {
diff --git a/net/devif/devif_cansend.c b/net/devif/devif_cansend.c
index 60fdf38..43570f2 100644
--- a/net/devif/devif_cansend.c
+++ b/net/devif/devif_cansend.c
@@ -80,10 +80,10 @@
  ****************************************************************************/
 
 /****************************************************************************
- * Name: devif_pkt_send
+ * Name: devif_can_send
  *
  * Description:
- *   Called from socket logic in order to send a raw packet in response to
+ *   Called from socket logic in order to send a can packet in response to
  *   an xmit or poll request from the network interface driver.
  *
  *   This is almost identical to calling devif_send() except that the data to


[incubator-nuttx] 02/31: include/netpacket/can.h: Add CAN socket family definitions

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch SocketCAN
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 5fa6d20e7c30724ae24de99aaff5d21960cc9019
Author: Gregory Nutt <gn...@nuttx.org>
AuthorDate: Thu Feb 13 09:58:12 2020 -0600

    include/netpacket/can.h:  Add CAN socket family definitions
---
 include/netpacket/can.h | 120 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 120 insertions(+)

diff --git a/include/netpacket/can.h b/include/netpacket/can.h
new file mode 100644
index 0000000..b93bb21
--- /dev/null
+++ b/include/netpacket/can.h
@@ -0,0 +1,120 @@
+/****************************************************************************
+ * include/netpacket/can.h
+ * Definitions for use with AF_PACKET sockets
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __INCLUDE_NETPACKET_CAN_H
+#define __INCLUDE_NETPACKET_CAN_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Special address description flags for the CAN_ID */
+
+#define CAN_EFF_FLAG 0x80000000  /* EFF/SFF is set in the MSB */
+#define CAN_RTR_FLAG 0x40000000  /* Remote transmission request */
+#define CAN_ERR_FLAG 0x20000000  /* Error message frame */
+
+/* Valid bits in CAN ID for frame formats */
+
+#define CAN_SFF_MASK 0x000007ff  /* Standard frame format (SFF) */
+#define CAN_EFF_MASK 0x1fffffff  /* Extended frame format (EFF) */
+#define CAN_ERR_MASK 0x1fffffff  /* Omit EFF, RTR, ERR flags */
+
+/* PF_CAN protocols */
+
+#define CAN_RAW      1           /* RAW sockets */
+#define CAN_BCM      2           /* Broadcast Manager */
+#define CAN_TP16     3           /* VAG Transport Protocol v1.6 */
+#define CAN_TP20     4           /* VAG Transport Protocol v2.0 */
+#define CAN_MCNET    5           /* Bosch MCNet */
+#define CAN_ISOTP    6           /* ISO 15765-2 Transport Protocol */
+#define CAN_J1939    7           /* SAE J1939 */
+#define CAN_NPROTO   8
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/* Controller Area Network Identifier structure
+ *
+ *   Bit 0-28: CAN identifier (11/29 bit)
+ *   Bit 29:   Error message frame flag (0 = data frame, 1 = error message)
+ *   Bit 30:   Remote transmission request flag (1 = rtr frame)
+ *   Bit 31:   Frame format flag (0 = standard 11 bit, 1 = extended 29 bit)
+ */
+
+typedef uint32_t canid_t;
+
+/* The sockaddr structure for CAN sockets
+ *
+ *   can_family:  Address family number AF_CAN.
+ *   can_ifindex: CAN network interface index.
+ *   can_addr:    Protocol specific address information
+ */
+
+struct sockaddr_can
+{
+  sa_family_t can_family;
+  int16_t     can_ifindex;
+  union
+    {
+      /* Transport protocol class address information */
+
+      struct
+      {
+        canid_t rx_id;
+        canid_t tx_id;
+      } tp;
+
+      /* J1939 address information */
+
+      struct
+      {
+        /* 8 byte name when using dynamic addressing */
+
+        uint64_t name;
+
+        /* pgn:
+         *   8 bit: PS in PDU2 case, else 0
+         *   8 bit: PF
+         *   1 bit: DP
+         *   1 bit: reserved
+         */
+
+      uint32_t pgn;
+
+      /* 1 byte address */
+
+      uint8_t addr;
+    } j1939;
+  } can_addr;
+};
+
+#endif /* __INCLUDE_NETPACKET_CAN_H */


[incubator-nuttx] 23/31: Code style fixes 2

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch SocketCAN
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit a30faa169564cf863a0085204523be7c85d2c286
Author: Jari van Ewijk <ja...@nxp.com>
AuthorDate: Fri Mar 13 14:30:32 2020 +0100

    Code style fixes 2
---
 include/sys/socket.h             | 13 +++++++------
 libs/libc/net/lib_recvmsg.c      |  3 ++-
 net/bluetooth/bluetooth_sockif.c | 34 ++++++++++++++++++----------------
 3 files changed, 27 insertions(+), 23 deletions(-)

diff --git a/include/sys/socket.h b/include/sys/socket.h
index 4cf40a7..87cb8e8 100644
--- a/include/sys/socket.h
+++ b/include/sys/socket.h
@@ -157,10 +157,10 @@
 #define SO_ERROR         4 /* Reports and clears error status (get only).
                             * arg: returns an integer value
                             */
-#define SO_KEEPALIVE     5 /* Keeps connections active by enabling the periodic
-                            * transmission of messages (get/set).
-                            * arg:  pointer to integer containing a boolean int
-                            * value
+#define SO_KEEPALIVE     5 /* Keeps connections active by enabling the
+                            * periodic transmission of messages (get/set).
+                            * arg:  pointer to integer containing a boolean
+                            * int value
                             */
 #define SO_LINGER        6 /* Lingers on a close() if data is present (get/set)
                             * arg: struct linger
@@ -194,8 +194,9 @@
                             * arg: integer value
                             */
 #define SO_SNDTIMEO     14 /* Sets the timeout value specifying the amount of
-                            * time that an output function blocks because flow
-                            * control prevents data from being sent(get/set).
+                            * time that an output function blocks because
+                            * flow control prevents data from being sent
+                            * (get/set).
                             * arg: struct timeval
                             */
 #define SO_TYPE         15 /* Reports the socket type (get only).
diff --git a/libs/libc/net/lib_recvmsg.c b/libs/libc/net/lib_recvmsg.c
index 2513dfa..5200acd 100644
--- a/libs/libc/net/lib_recvmsg.c
+++ b/libs/libc/net/lib_recvmsg.c
@@ -53,7 +53,8 @@
  * Function: recvmsg
  *
  * Description:
- *   The recvmsg() call is identical to recvfrom() with a NULL from parameter.
+ *   The recvmsg() call is identical to recvfrom() with a NULL from
+ *   parameter.
  *
  * Parameters:
  *   sockfd   Socket descriptor of socket
diff --git a/net/bluetooth/bluetooth_sockif.c b/net/bluetooth/bluetooth_sockif.c
index 4f4b936..fd6d95f 100644
--- a/net/bluetooth/bluetooth_sockif.c
+++ b/net/bluetooth/bluetooth_sockif.c
@@ -106,7 +106,7 @@ const struct sock_intf_s g_bluetooth_sockif =
   bluetooth_send,        /* si_send */
   bluetooth_sendto,      /* si_sendto */
 #ifdef CONFIG_NET_SENDFILE
-  NULL,                   /* si_sendfile */
+  NULL,                  /* si_sendfile */
 #endif
   bluetooth_recvfrom,    /* si_recvfrom */
 #ifdef CONFIG_NET_RECVMSG_CMSG
@@ -246,10 +246,10 @@ static void bluetooth_addref(FAR struct socket *psock)
  * Name: bluetooth_connect
  *
  * Description:
- *   bluetooth_connect() connects the local socket referred to by the structure
- *   'psock' to the address specified by 'addr'. The addrlen argument
- *   specifies the size of 'addr'.  The format of the address in 'addr' is
- *   determined by the address space of the socket 'psock'.
+ *   bluetooth_connect() connects the local socket referred to by the
+ *   structure 'psock' to the address specified by 'addr'. The addrlen
+ *   argument specifies the size of 'addr'.  The format of the address in
+ *   'addr' is determined by the address space of the socket 'psock'.
  *
  *   Generally, connection-based protocol sockets may successfully
  *   bluetooth_connect() only once; connectionless protocol sockets may use
@@ -333,7 +333,8 @@ static int bluetooth_connect(FAR struct socket *psock,
  * Input Parameters:
  *   psock    Reference to the listening socket structure
  *   addr     Receives the address of the connecting client
- *   addrlen  Input: allocated size of 'addr', Return: returned size of 'addr'
+ *   addrlen  Input: allocated size of 'addr',
+ *            Return: returned size of 'addr'
  *   newsock  Location to return the accepted socket information.
  *
  * Returned Value:
@@ -375,7 +376,7 @@ static int bluetooth_accept(FAR struct socket *psock,
  ****************************************************************************/
 
 static int bluetooth_bind(FAR struct socket *psock,
-                           FAR const struct sockaddr *addr, socklen_t addrlen)
+                          FAR const struct sockaddr *addr, socklen_t addrlen)
 {
   FAR const struct sockaddr_bt_s *iaddr;
   FAR struct radio_driver_s *radio;
@@ -442,10 +443,10 @@ static int bluetooth_bind(FAR struct socket *psock,
  * Name: bluetooth_getsockname
  *
  * Description:
- *   The bluetooth_getsockname() function retrieves the locally-bound name of the
- *   specified packet socket, stores this address in the sockaddr structure
- *   pointed to by the 'addr' argument, and stores the length of this
- *   address in the object pointed to by the 'addrlen' argument.
+ *   The bluetooth_getsockname() function retrieves the locally-bound name of
+ *   the specified packet socket, stores this address in the sockaddr
+ *   structure pointed to by the 'addr' argument, and stores the length of
+ *   this address in the object pointed to by the 'addrlen' argument.
  *
  *   If the actual length of the address is greater than the length of the
  *   supplied sockaddr structure, the stored address will be truncated.
@@ -504,8 +505,8 @@ static int bluetooth_getsockname(FAR struct socket *psock,
  * Name: bluetooth_getpeername
  *
  * Description:
- *   The bluetooth_getpeername() function retrieves the remote-connected name of
- *   the specified local socket, stores this address in the sockaddr
+ *   The bluetooth_getpeername() function retrieves the remote-connected name
+ *   of the specified local socket, stores this address in the sockaddr
  *   structure pointed to by the 'addr' argument, and stores the length of
  *   this address in the object pointed to by the 'addrlen' argument.
  *
@@ -708,9 +709,10 @@ static ssize_t bluetooth_send(FAR struct socket *psock, FAR const void *buf,
  *
  ****************************************************************************/
 
-static ssize_t bluetooth_sendto(FAR struct socket *psock, FAR const void *buf,
-                                 size_t len, int flags,
-                                 FAR const struct sockaddr *to, socklen_t tolen)
+static ssize_t bluetooth_sendto(FAR struct socket *psock,
+                                FAR const void *buf, size_t len, int flags,
+                                FAR const struct sockaddr *to,
+                                socklen_t tolen)
 {
   ssize_t ret;
 


[incubator-nuttx] 14/31: SocketCAN recfrom added non-blocking behavior support FlexCAN support sending extended CAN id

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch SocketCAN
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit cb0027fceeefec10b6f3e1411d3efa90649cf374
Author: Peter van der Perk <pe...@nxp.com>
AuthorDate: Fri Mar 6 15:20:15 2020 +0100

    SocketCAN recfrom added non-blocking behavior support
    FlexCAN support sending extended CAN id
---
 arch/arm/src/s32k1xx/s32k1xx_flexcan.c |  5 +++--
 net/can/can_recvfrom.c                 | 25 ++++++++++++++++++++++---
 2 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/arch/arm/src/s32k1xx/s32k1xx_flexcan.c b/arch/arm/src/s32k1xx/s32k1xx_flexcan.c
index f394a20..2e73dc9 100644
--- a/arch/arm/src/s32k1xx/s32k1xx_flexcan.c
+++ b/arch/arm/src/s32k1xx/s32k1xx_flexcan.c
@@ -113,6 +113,7 @@
 #define CAN_FIFO_NE                 (1 << 5)
 #define CAN_FIFO_OV                 (1 << 6)
 #define CAN_FIFO_WARN               (1 << 7)
+#define CAN_EFF_FLAG                0x80000000 /* EFF/SFF is set in the MSB */
 
 #define POOL_SIZE                   1
 
@@ -463,7 +464,7 @@ static int s32k1xx_transmit(FAR struct s32k1xx_driver_s *priv)
     {
 	  struct can_frame *frame = (struct can_frame *)priv->dev.d_buf;
 
-	  if (0) /* FIXME detect Std or Ext id */
+	  if (frame->can_id & CAN_EFF_FLAG)
 	    {
 	      cs.ide = 1;
 	      mb->id.ext = frame->can_id & MASKEXTID;
@@ -489,7 +490,7 @@ static int s32k1xx_transmit(FAR struct s32k1xx_driver_s *priv)
 
   	  cs.edl = 1; /* CAN FD Frame */
 
-  	  if (0) /* FIXME detect Std or Ext id */
+  	  if (frame->can_id & CAN_EFF_FLAG)
   	    {
   	      cs.ide = 1;
   	      mb->id.ext = frame->can_id & MASKEXTID;
diff --git a/net/can/can_recvfrom.c b/net/can/can_recvfrom.c
index f83d07c..c23af93 100644
--- a/net/can/can_recvfrom.c
+++ b/net/can/can_recvfrom.c
@@ -231,6 +231,8 @@ static inline int can_readahead(struct can_recvfrom_s *pstate)
   /* Check there is any CAN data already buffered in a read-ahead
    * buffer.
    */
+  
+  pstate->pr_recvlen = -1;
 
   if ((iob = iob_peek_queue(&conn->readahead)) != NULL &&
       pstate->pr_buflen > 0)
@@ -463,10 +465,27 @@ ssize_t can_recvfrom(FAR struct socket *psock, FAR void *buf,
 
   ret = can_readahead(&state);
   if (ret > 0)
+    {      
+      goto errout_with_state;
+    }
+    
+  ret = state.pr_recvlen;
+
+  /* Handle non-blocking CAN sockets */
+
+  if (_SS_ISNONBLOCK(psock->s_flags) || (flags & MSG_DONTWAIT) != 0)
     {
-      net_unlock();
-      nxsem_destroy(&state.pr_sem);
-      return ret;
+      /* Return the number of bytes read from the read-ahead buffer if
+       * something was received (already in 'ret'); EAGAIN if not.
+       */
+
+      if (ret < 0)
+        {
+          /* Nothing was received */
+
+          ret = -EAGAIN;          
+          goto errout_with_state;
+        }
     }
 
   /* Get the device driver that will service this transfer */


[incubator-nuttx] 06/31: SocketCAN initial receive working as well

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch SocketCAN
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit d7db889545f13e1b3d53810435f986a4d79aeb96
Author: Peter van der Perk <pe...@nxp.com>
AuthorDate: Thu Feb 20 16:06:15 2020 +0100

    SocketCAN initial receive working as well
---
 arch/arm/src/s32k1xx/s32k1xx_flexcan.c | 462 ++++++++++++++++++++++-----------
 net/can/Make.defs                      |   6 +-
 net/can/can.h                          |  28 ++
 net/can/can_input.c                    | 129 +++++++++
 net/can/can_recvfrom.c                 | 354 +++++++++++++++++++++++++
 net/can/can_sockif.c                   |  55 +---
 net/devif/Make.defs                    |   6 +-
 7 files changed, 836 insertions(+), 204 deletions(-)

diff --git a/arch/arm/src/s32k1xx/s32k1xx_flexcan.c b/arch/arm/src/s32k1xx/s32k1xx_flexcan.c
index 7046050..9c7a7d7 100644
--- a/arch/arm/src/s32k1xx/s32k1xx_flexcan.c
+++ b/arch/arm/src/s32k1xx/s32k1xx_flexcan.c
@@ -115,19 +115,23 @@
 #  error "Need at least one RX buffer"
 #endif*/
 
-#define MaskStdID                   0x000007FF;
-#define MaskExtID                   0x1FFFFFFF;
+#define MaskStdID                   0x000007FF
+#define MaskExtID                   0x1FFFFFFF
+#define FlagEFF                     (1 << 31) /* Extended frame format */
+#define FlagRTR                     (1 << 30) /* Remote transmission request */
 
 //Fixme nice variables/constants
-#define RxMBCount                   10
-#define TxMBCount                   6
-#define TotalMBcount                RxMBCount + TxMBCount
-#define TXMBMask                    (((1 << TxMBCount)-1) << RxMBCount)
+#define RxMBCount                   6
+#define FilterCount                 0
+#define RxandFilterMBCount          (RxMBCount + FilterCount)
+#define TxMBCount                   12 //???????????? why 12 idk it works
+#define TotalMBcount                RxandFilterMBCount + TxMBCount
+#define TXMBMask                    (((1 << TxMBCount)-1) << RxandFilterMBCount)
 
 #define CAN_FIFO_NE                 (1 << 5)
 #define CAN_FIFO_OV                 (1 << 6)
 #define CAN_FIFO_WARN               (1 << 7)
-#define FIFO_IFLAG1                 CAN_FIFO_NE | CAN_FIFO_WARN | CAN_FIFO_OV
+#define FIFO_IFLAG1                 (CAN_FIFO_NE | CAN_FIFO_WARN | CAN_FIFO_OV)
 
 static int peak_tx_mailbox_index_ = 0;
 
@@ -345,6 +349,12 @@ static bool s32k1xx_txringfull(FAR struct s32k1xx_driver_s *priv);
 static int  s32k1xx_transmit(FAR struct s32k1xx_driver_s *priv);
 static int  s32k1xx_txpoll(struct net_driver_s *dev);
 
+/* Helper functions */
+static void s32k1xx_setenable(uint32_t enable);
+static void s32k1xx_setfreeze(uint32_t freeze);
+static uint32_t s32k1xx_waitmcr_change(uint32_t mask,
+		                             uint32_t target_state);
+
 /* Interrupt handling */
 
 static void s32k1xx_dispatch(FAR struct s32k1xx_driver_s *priv);
@@ -385,6 +395,7 @@ static int  s32k1xx_ioctl(struct net_driver_s *dev, int cmd,
 /* Initialization */
 
 static void s32k1xx_initbuffers(struct s32k1xx_driver_s *priv);
+static int  s32k1xx_initialize(struct s32k1xx_driver_s *priv);
 static void s32k1xx_reset(struct s32k1xx_driver_s *priv);
 
 /****************************************************************************
@@ -462,7 +473,7 @@ static int s32k1xx_transmit(FAR struct s32k1xx_driver_s *priv)
 	  mbi = (getreg32(S32K1XX_CAN0_ESR2) & CAN_ESR2_LPTM_MASK) >> CAN_ESR2_LPTM_SHIFT;
   }
 
-  uint32_t mb_bit = 1 << (RxMBCount + mbi);
+  uint32_t mb_bit = 1 << (RxandFilterMBCount + mbi);
 
   while (mbi < TxMBCount)
   {
@@ -476,8 +487,9 @@ static int s32k1xx_transmit(FAR struct s32k1xx_driver_s *priv)
 	  mbi++;
   }
 
-  if (mbi == TxMBCount)
+  if ((mbi-RxandFilterMBCount) == TxMBCount)
   {
+	  nwarn("No TX MB available mbi %i\r\n", mbi);
 	  return 0;       // No transmission for you!
   }
 
@@ -644,7 +656,96 @@ static inline void s32k1xx_dispatch(FAR struct s32k1xx_driver_s *priv)
 static void s32k1xx_receive(FAR struct s32k1xx_driver_s *priv)
 {
   #warning Missing logic
-	ninfo("FLEXCAN: receive\r\n");
+	//ninfo("FLEXCAN: receive\r\n");
+
+	s32k1xx_gpiowrite(PIN_PORTD | PIN31, 1);
+
+	struct can_frame frame;
+	uint32_t flags = getreg32(S32K1XX_CAN0_IFLAG1);
+
+	if ((flags & FIFO_IFLAG1) == 0)
+	{
+		// Weird, IRQ is here but no data to read
+		return;
+	}
+
+	if (flags & CAN_FIFO_OV)
+	{
+		//error_cnt_++;
+		putreg32(CAN_FIFO_OV, S32K1XX_CAN0_IFLAG1);
+	}
+
+	if (flags & CAN_FIFO_WARN)
+	{
+		//fifo_warn_cnt_++;
+		putreg32(CAN_FIFO_WARN, S32K1XX_CAN0_IFLAG1);
+	}
+
+	if (flags & CAN_FIFO_NE)
+	{
+		struct MbRx *rf = priv->rx;
+
+		/*
+		 * Read the frame contents
+		 */
+
+		if (rf->CS.ide)
+		{
+			frame.can_id = MaskExtID & rf->ID.ext;
+			frame.can_id |= FlagEFF;
+		}
+		else
+		{
+			frame.can_id = MaskStdID & rf->ID.std;
+		}
+
+		if (rf->CS.rtr)
+		{
+			frame.can_id |= FlagRTR;
+		}
+
+		frame.can_dlc = rf->CS.dlc;
+
+		frame.data[0] = rf->data.b0;
+		frame.data[1] = rf->data.b1;
+		frame.data[2] = rf->data.b2;
+		frame.data[3] = rf->data.b3;
+		frame.data[4] = rf->data.b4;
+		frame.data[5] = rf->data.b5;
+		frame.data[6] = rf->data.b6;
+		frame.data[7] = rf->data.b7;
+
+
+		putreg32(CAN_FIFO_NE, S32K1XX_CAN0_IFLAG1);
+
+		/* Copy the buffer pointer to priv->dev.d_buf.  Set amount of data
+		 * in priv->dev.d_len
+		 */
+
+		priv->dev.d_len = sizeof(struct can_frame);
+		priv->dev.d_buf =
+				(uint8_t *)s32k1xx_swap32((uint32_t)&frame); //FIXME
+
+		/* Invalidate the buffer so that the correct packet will be re-read
+		 * from memory when the packet content is accessed.
+		 */
+
+		up_invalidate_dcache((uintptr_t)priv->dev.d_buf,
+				(uintptr_t)priv->dev.d_buf + priv->dev.d_len);
+
+		/* Send to socket interface */
+		NETDEV_RXPACKETS(&priv->dev);
+
+		can_input(&priv->dev);
+
+
+
+
+		/*
+		 * Store with timeout into the FIFO buffer and signal update event
+		 */
+
+	}
 }
 
 /****************************************************************************
@@ -736,9 +837,6 @@ static void s32k1xx_flexcan_interrupt_work(FAR void *arg)
 static int s32k1xx_flexcan_interrupt(int irq, FAR void *context, FAR void *arg)
 {
   #warning Missing logic
-
-	ninfo("FLEXCAN INT %i\r\n", irq);
-
 	FAR struct s32k1xx_driver_s *priv = &g_flexcan[0];
 	uint32_t flags;
 	flags  = getreg32(S32K1XX_CAN0_IFLAG1);
@@ -881,6 +979,24 @@ static void s32k1xx_polltimer_expiry(int argc, uint32_t arg, ...)
   work_queue(ETHWORK, &priv->pollwork, s32k1xx_poll_work, priv, 0);
 }
 
+static void s32k1xx_setenable(uint32_t enable)
+{
+	uint32_t regval;
+	if(enable)
+	{
+		regval  = getreg32(S32K1XX_CAN0_MCR);
+		regval &= ~(CAN_MCR_MDIS);
+		putreg32(regval, S32K1XX_CAN0_MCR);
+	}
+	else
+	{
+		regval  = getreg32(S32K1XX_CAN0_MCR);
+		regval |= CAN_MCR_MDIS;
+		putreg32(regval, S32K1XX_CAN0_MCR);
+	}
+	s32k1xx_waitmcr_change(CAN_MCR_LPMACK,1);
+}
+
 static void s32k1xx_setfreeze(uint32_t freeze)
 {
 	uint32_t regval;
@@ -945,136 +1061,13 @@ static int s32k1xx_ifup(struct net_driver_s *dev)
   uint32_t regval;
 
   #warning Missing logic
-  ninfo("FLEXCAN: test ifup\r\n");
-
-  /* initialize CAN device */
-  //FIXME we only support a single can device for now
-
-  //TEST GPIO tming
-  s32k1xx_pinconfig(PIN_PORTD | PIN31 | GPIO_OUTPUT);
-
 
-  regval  = getreg32(S32K1XX_CAN0_MCR);
-  regval |= CAN_MCR_MDIS;
-  putreg32(regval, S32K1XX_CAN0_MCR);
-
-  /* Set SYS_CLOCK src */
-  regval  = getreg32(S32K1XX_CAN0_CTRL1);
-  regval |= CAN_CTRL1_CLKSRC;
-  putreg32(regval, S32K1XX_CAN0_CTRL1);
-
-  regval  = getreg32(S32K1XX_CAN0_MCR);
-  regval &= ~(CAN_MCR_MDIS);
-  putreg32(regval, S32K1XX_CAN0_MCR);
-
-
-  regval  = getreg32(S32K1XX_CAN0_MCR);
-  regval |= CAN_MCR_RFEN | CAN_MCR_SLFWAK | CAN_MCR_WRNEN | CAN_MCR_SRXDIS
-		  | CAN_MCR_IRMQ | CAN_MCR_AEN |
-		  (((TotalMBcount - 1) << CAN_MCR_MAXMB_SHIFT) & CAN_MCR_MAXMB_MASK);
-  putreg32(regval, S32K1XX_CAN0_MCR);
-
-  regval  = CAN_CTRL2_RRS | CAN_CTRL2_EACEN | CAN_CTRL2_RFFN_16MB; //FIXME TASD
-  putreg32(regval, S32K1XX_CAN0_CTRL2);
-
-  /* Enter freeze mode */
-  s32k1xx_setfreeze(1);
-  if(!s32k1xx_waitfreezeack_change(1))
+  if(!s32k1xx_initialize(priv))
   {
-	  ninfo("FLEXCAN: freeze fail\r\n");
+	  nerr("initialize failed");
 	  return -1;
   }
 
-  /*regval  = getreg32(S32K1XX_CAN0_CTRL1);
-  regval |= ((0  << CAN_CTRL1_PRESDIV_SHIFT) & CAN_CTRL1_PRESDIV_MASK)
-		  | ((46 << CAN_CTRL1_ROPSEG_SHIFT) & CAN_CTRL1_ROPSEG_MASK)
-	      | ((18 << CAN_CTRL1_PSEG1_SHIFT) & CAN_CTRL1_PSEG1_MASK)
-		  | ((12 << CAN_CTRL1_PSEG2_SHIFT) & CAN_CTRL1_PSEG2_MASK)
-		  | ((12 << CAN_CTRL1_RJW_SHIFT) & CAN_CTRL1_RJW_MASK)
-		  | CAN_CTRL1_ERRMSK
-		  | CAN_CTRL1_TWRNMSK
-		  | CAN_CTRL1_RWRNMSK;
-
-  putreg32(regval, S32K1XX_CAN0_CTRL1);*/
-
-  /* CAN Bit Timing (CBT) configuration for a nominal phase of 1 Mbit/s
-   * with 80 time quantas,in accordance with Bosch 2012 specification,
-   * sample point at 83.75% */
-  regval  = getreg32(S32K1XX_CAN0_CBT);
-  regval |= CAN_CBT_BTF |     /* Enable extended bit timing configurations for CAN-FD
-                                      for setting up separetely nominal and data phase */
-            CAN_CBT_EPRESDIV(0) |  /* Prescaler divisor factor of 1 */
-            CAN_CBT_EPROPSEG(46) | /* Propagation segment of 47 time quantas */
-            CAN_CBT_EPSEG1(18) |   /* Phase buffer segment 1 of 19 time quantas */
-            CAN_CBT_EPSEG2(12) |   /* Phase buffer segment 2 of 13 time quantas */
-            CAN_CBT_ERJW(12);      /* Resynchronization jump width same as PSEG2 */
-  putreg32(regval, S32K1XX_CAN0_CBT);
-
-#ifdef CAN_FD
-
-  /* Enable CAN FD feature */
-  regval  = getreg32(S32K1XX_CAN0_MCR);
-  regval |= CAN_MCR_FDEN;
-  putreg32(regval, S32K1XX_CAN0_MCR);
-
-  /* CAN-FD Bit Timing (FDCBT) for a data phase of 4 Mbit/s with 20 time quantas,
-                 in accordance with Bosch 2012 specification, sample point at 75% */
-  regval  = getreg32(S32K1XX_CAN0_FDCBT);
-  regval |= CAN_FDCBT_FPRESDIV(0) | /* Prescaler divisor factor of 1 */
-		  CAN_FDCBT_FPROPSEG(7) | /* Propagation semgment of 7 time quantas
-                                                              (only register that doesn't add 1) */
-		  CAN_FDCBT_FPSEG1(6) |   /* Phase buffer segment 1 of 7 time quantas */
-		  CAN_FDCBT_FPSEG2(4) |   /* Phase buffer segment 2 of 5 time quantas */
-		  CAN_FDCBT_FRJW(4);      /* Resynchorinzation jump width same as PSEG2 */
-  putreg32(regval, S32K1XX_CAN0_FDCBT);
-
-  /* Additional CAN-FD configurations */
-  regval  = getreg32(S32K1XX_CAN0_FDCTRL);
-  regval |= CAN_FDCTRL_FDRATE | /* Enable bit rate switch in data phase of frame */
-		  CAN_FDCTRL_TDCEN |  /* Enable transceiver delay compensation */
-		  CAN_FDCTRL_TDCOFF(5) |   /* Setup 5 cycles for data phase sampling delay */
-		  CAN_FDCTRL_MBDSR0(3);    /* Setup 64 bytes per message buffer (7 MB's) */
-  putreg32(regval, S32K1XX_CAN0_FDCTRL);
-
-  regval  = getreg32(S32K1XX_CAN0_CTRL2);
-  regval |= CAN_CTRL2_ISOCANFDEN;
-  putreg32(regval, S32K1XX_CAN0_CTRL2);
-#endif
-
-
-
-  /* Iniatilize all MB rx and tx */
-  for(int i = 0; i < TotalMBcount; i++)
-  {
-	  ninfo("MB %i %p\r\n", i, &priv->rx[i]);
-	  ninfo("MB %i %p\r\n", i, &priv->rx[i].ID.w);
-	  priv->rx[i].CS.cs = 0x0;
-	  priv->rx[i].ID.w = 0x0;
-	  priv->rx[i].data.l = 0x0;
-	  priv->rx[i].data.h = 0x0;
-  }
-
-  /* Filtering catchall */
-  putreg32(0x0, S32K1XX_CAN0_RXFGMASK);
-
-  for(int i = 0; i < TotalMBcount; i++)
-  {
-	  putreg32(0,S32K1XX_CAN0_RXIMR(i));
-  }
-
-  putreg32(FIFO_IFLAG1 | TXMBMask, S32K1XX_CAN0_IFLAG1);
-  putreg32(FIFO_IFLAG1, S32K1XX_CAN0_IMASK1);
-
-
-  /* Exit freeze mode */
-  s32k1xx_setfreeze(0);
-  if(!s32k1xx_waitfreezeack_change(0))
-  {
-	  ninfo("FLEXCAN: unfreeze fail\r\n");
-	  return -1;
-  }
-
-
   /* Set and activate a timer process */
 
   wd_start(priv->txpoll, S32K1XX_WDDELAY, s32k1xx_polltimer_expiry, 1,
@@ -1190,8 +1183,11 @@ static int s32k1xx_txavail(struct net_driver_s *dev)
   if (work_available(&priv->pollwork))
     {
       /* Schedule to serialize the poll on the worker thread. */
-
+#ifdef WORK_QUEUE_BYPASS
+	  s32k1xx_txavail_work(priv);
+#else
       work_queue(ETHWORK, &priv->pollwork, s32k1xx_txavail_work, priv, 0);
+#endif
     }
 
   return OK;
@@ -1233,6 +1229,138 @@ static int s32k1xx_ioctl(struct net_driver_s *dev, int cmd,
 }
 #endif /* CONFIG_NETDEV_IOCTL */
 
+/****************************************************************************
+ * Function: s32k1xx_initalize
+ *
+ * Description:
+ *   Initialize FLEXCAN device
+ *
+ * Input Parameters:
+ *   priv - Reference to the private FLEXCAN driver state structure
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static int s32k1xx_initialize(struct s32k1xx_driver_s *priv)
+{
+	uint32_t regval;
+	uint32_t i;
+
+	/* initialize CAN device */
+	//FIXME we only support a single can device for now
+
+	//TEST GPIO tming
+	s32k1xx_pinconfig(PIN_PORTD | PIN31 | GPIO_OUTPUT);
+
+
+	s32k1xx_setenable(0);
+
+	/* Set SYS_CLOCK src */
+	regval  = getreg32(S32K1XX_CAN0_CTRL1);
+	regval |= CAN_CTRL1_CLKSRC;
+	putreg32(regval, S32K1XX_CAN0_CTRL1);
+
+	s32k1xx_setenable(1);
+
+	s32k1xx_reset(priv);
+
+	/* Enter freeze mode */
+	s32k1xx_setfreeze(1);
+	if(!s32k1xx_waitfreezeack_change(1))
+	{
+		ninfo("FLEXCAN: freeze fail\r\n");
+		return -1;
+	}
+
+	/*regval  = getreg32(S32K1XX_CAN0_CTRL1);
+	regval |= ((0  << CAN_CTRL1_PRESDIV_SHIFT) & CAN_CTRL1_PRESDIV_MASK)
+					  | ((46 << CAN_CTRL1_ROPSEG_SHIFT) & CAN_CTRL1_ROPSEG_MASK)
+					  | ((18 << CAN_CTRL1_PSEG1_SHIFT) & CAN_CTRL1_PSEG1_MASK)
+					  | ((12 << CAN_CTRL1_PSEG2_SHIFT) & CAN_CTRL1_PSEG2_MASK)
+					  | ((12 << CAN_CTRL1_RJW_SHIFT) & CAN_CTRL1_RJW_MASK)
+					  | CAN_CTRL1_ERRMSK
+					  | CAN_CTRL1_TWRNMSK
+					  | CAN_CTRL1_RWRNMSK;
+
+	putreg32(regval, S32K1XX_CAN0_CTRL1);*/
+
+#define BIT_METHOD2
+#ifdef BIT_METHOD2
+	/* CAN Bit Timing (CBT) configuration for a nominal phase of 1 Mbit/s
+	 * with 80 time quantas,in accordance with Bosch 2012 specification,
+	 * sample point at 83.75% */
+	regval  = getreg32(S32K1XX_CAN0_CBT);
+	regval |= CAN_CBT_BTF |     /* Enable extended bit timing configurations for CAN-FD
+	                                      for setting up separetely nominal and data phase */
+			CAN_CBT_EPRESDIV(0) |  /* Prescaler divisor factor of 1 */
+			CAN_CBT_EPROPSEG(46) | /* Propagation segment of 47 time quantas */
+			CAN_CBT_EPSEG1(18) |   /* Phase buffer segment 1 of 19 time quantas */
+			CAN_CBT_EPSEG2(12) |   /* Phase buffer segment 2 of 13 time quantas */
+			CAN_CBT_ERJW(12);      /* Resynchronization jump width same as PSEG2 */
+	putreg32(regval, S32K1XX_CAN0_CBT);
+#endif
+
+#ifdef CAN_FD
+
+	/* Enable CAN FD feature */
+	regval  = getreg32(S32K1XX_CAN0_MCR);
+	regval |= CAN_MCR_FDEN;
+	putreg32(regval, S32K1XX_CAN0_MCR);
+
+	/* CAN-FD Bit Timing (FDCBT) for a data phase of 4 Mbit/s with 20 time quantas,
+	                 in accordance with Bosch 2012 specification, sample point at 75% */
+	regval  = getreg32(S32K1XX_CAN0_FDCBT);
+	regval |= CAN_FDCBT_FPRESDIV(0) | /* Prescaler divisor factor of 1 */
+			CAN_FDCBT_FPROPSEG(7) | /* Propagation semgment of 7 time quantas
+	                                                              (only register that doesn't add 1) */
+			CAN_FDCBT_FPSEG1(6) |   /* Phase buffer segment 1 of 7 time quantas */
+			CAN_FDCBT_FPSEG2(4) |   /* Phase buffer segment 2 of 5 time quantas */
+			CAN_FDCBT_FRJW(4);      /* Resynchorinzation jump width same as PSEG2 */
+	putreg32(regval, S32K1XX_CAN0_FDCBT);
+
+	/* Additional CAN-FD configurations */
+	regval  = getreg32(S32K1XX_CAN0_FDCTRL);
+	regval |= CAN_FDCTRL_FDRATE | /* Enable bit rate switch in data phase of frame */
+			CAN_FDCTRL_TDCEN |  /* Enable transceiver delay compensation */
+			CAN_FDCTRL_TDCOFF(5) |   /* Setup 5 cycles for data phase sampling delay */
+			CAN_FDCTRL_MBDSR0(3);    /* Setup 64 bytes per message buffer (7 MB's) */
+	putreg32(regval, S32K1XX_CAN0_FDCTRL);
+
+	regval  = getreg32(S32K1XX_CAN0_CTRL2);
+	regval |= CAN_CTRL2_ISOCANFDEN;
+	putreg32(regval, S32K1XX_CAN0_CTRL2);
+#endif
+
+	for(i = TxMBCount; i < TotalMBcount; i++)
+	{
+		priv->rx[i].ID.w = 0x0;
+	}
+
+	putreg32(0x0, S32K1XX_CAN0_RXFGMASK);
+
+	for(i = 0; i < TotalMBcount; i++)
+	{
+		putreg32(0,S32K1XX_CAN0_RXIMR(i));
+	}
+
+	putreg32(FIFO_IFLAG1 | TXMBMask, S32K1XX_CAN0_IFLAG1);
+	putreg32(FIFO_IFLAG1, S32K1XX_CAN0_IMASK1);
+
+
+	/* Exit freeze mode */
+	s32k1xx_setfreeze(0);
+	if(!s32k1xx_waitfreezeack_change(0))
+	{
+		ninfo("FLEXCAN: unfreeze fail\r\n");
+		return -1;
+	}
+
+	return 1;
+}
 
 /****************************************************************************
  * Function: s32k1xx_initbuffers
@@ -1273,19 +1401,57 @@ static void s32k1xx_initbuffers(struct s32k1xx_driver_s *priv)
 
 static void s32k1xx_reset(struct s32k1xx_driver_s *priv)
 {
-  unsigned int i;
+	uint32_t regval;
+	uint32_t i;
 
-  /* Set the reset bit and clear the enable bit */
+	regval  = getreg32(S32K1XX_CAN0_MCR);
+	regval |= CAN_MCR_SOFTRST;
+	putreg32(regval, S32K1XX_CAN0_MCR);
 
-  
-  #warning Missing logic
+	if(!s32k1xx_waitmcr_change(CAN_MCR_SOFTRST, 0))
+	{
+		nerr("Reset failed");
+		return;
+	}
 
-  /* Wait at least 8 clock cycles */
+	/* TODO calculate TASD */
 
-  for (i = 0; i < 10; i++)
-    {
-      asm volatile ("nop");
-    }
+
+	regval  = getreg32(S32K1XX_CAN0_MCR);
+	regval &= ~(CAN_MCR_SUPV);
+	putreg32(regval, S32K1XX_CAN0_MCR);
+
+	/* Initialize all MB rx and tx */
+	for(i = 0; i < TotalMBcount; i++)
+	{
+		ninfo("MB %i %p\r\n", i, &priv->rx[i]);
+		ninfo("MB %i %p\r\n", i, &priv->rx[i].ID.w);
+		priv->rx[i].CS.cs = 0x0;
+		priv->rx[i].ID.w = 0x0;
+		priv->rx[i].data.l = 0x0;
+		priv->rx[i].data.h = 0x0;
+	}
+
+	regval  = getreg32(S32K1XX_CAN0_MCR);
+	regval |= CAN_MCR_RFEN | CAN_MCR_SLFWAK | CAN_MCR_WRNEN | CAN_MCR_SRXDIS
+			| CAN_MCR_IRMQ | CAN_MCR_AEN |
+			(((TotalMBcount - 1) << CAN_MCR_MAXMB_SHIFT) & CAN_MCR_MAXMB_MASK);
+	putreg32(regval, S32K1XX_CAN0_MCR);
+
+	regval  = CAN_CTRL2_RRS | CAN_CTRL2_EACEN | CAN_CTRL2_RFFN_16MB; //FIXME TASD
+	putreg32(regval, S32K1XX_CAN0_CTRL2);
+
+
+	for(i = 0; i < TotalMBcount; i++)
+	{
+		putreg32(0,S32K1XX_CAN0_RXIMR(i));
+	}
+
+	/* Filtering catchall */
+	putreg32(0x3FFFFFFF, S32K1XX_CAN0_RX14MASK);
+	putreg32(0x3FFFFFFF, S32K1XX_CAN0_RX15MASK);
+	putreg32(0x3FFFFFFF, S32K1XX_CAN0_RXMGMASK);
+	putreg32(0x0, S32K1XX_CAN0_RXFGMASK);
 }
 
 /****************************************************************************
diff --git a/net/can/Make.defs b/net/can/Make.defs
index f8488c0..d078a05 100644
--- a/net/can/Make.defs
+++ b/net/can/Make.defs
@@ -26,13 +26,15 @@ ifeq ($(CONFIG_NET_CAN),y)
 
 SOCK_CSRCS += can_sockif.c
 SOCK_CSRCS += can_send.c
+SOCK_CSRCS += can_recvfrom.c
 
 NET_CSRCS += can_conn.c
-NET_CSRCS += can_poll.c
+NET_CSRCS += can_input.c
 NET_CSRCS += can_callback.c
+NET_CSRCS += can_poll.c
 
 # Include can build support
 
 DEPPATH += --dep-path can
 VPATH += :can
-endif
+endif # CONFIG_NET_CAN
diff --git a/net/can/can.h b/net/can/can.h
index 3fed49b..c2b6857 100644
--- a/net/can/can.h
+++ b/net/can/can.h
@@ -166,6 +166,34 @@ uint16_t can_callback(FAR struct net_driver_s *dev,
                       FAR struct can_conn_s *conn, uint16_t flags);
 
 /****************************************************************************
+ * Name: can_recvfrom
+ *
+ * Description:
+ *   Implements the socket recvfrom interface pkt_recvfrom() receives messages from
+ *   a socket, and may be used to receive data on a socket whether or not it
+ *   is connection-oriented.
+ *
+ * Input Parameters:
+ *   psock    A pointer to a NuttX-specific, internal socket structure
+ *   buf      Buffer to receive data
+ *   len      Length of buffer
+ *   flags    Receive flags
+ *   from     Address of source (may be NULL)
+ *   fromlen  The length of the address structure
+ *
+ * Returned Value:
+ *   On success, returns the number of characters received.  If no data is
+ *   available to be received and the peer has performed an orderly shutdown,
+ *   recv() will return 0.  Otherwise, on errors, a negated errno value is
+ *   returned (see recvfrom() for the list of appropriate error values).
+ *
+ ****************************************************************************/
+
+ssize_t can_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
+                     int flags, FAR struct sockaddr *from,
+                     FAR socklen_t *fromlen);
+
+/****************************************************************************
  * Name: can_poll
  *
  * Description:
diff --git a/net/can/can_input.c b/net/can/can_input.c
new file mode 100644
index 0000000..32dcebf
--- /dev/null
+++ b/net/can/can_input.c
@@ -0,0 +1,129 @@
+/****************************************************************************
+ * net/can/can_input.c
+ * Handling incoming packet input
+ *
+ *   Copyright (C) 2014, 2020 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <gn...@nuttx.org>
+ *
+ * Adapted for NuttX from logic in uIP which also has a BSD-like license:
+ *
+ *   Original author Adam Dunkels <ad...@dunkels.com>
+ *   Copyright () 2001-2003, Adam Dunkels.
+ *   All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#if defined(CONFIG_NET) && defined(CONFIG_NET_CAN)
+
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/net/netdev.h>
+#include <nuttx/net/can.h>
+
+#include "devif/devif.h"
+#include "can/can.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: can_input
+ *
+ * Description:
+ *   Handle incoming packet input
+ *
+ * Input Parameters:
+ *   dev - The device driver structure containing the received packet
+ *
+ * Returned Value:
+ *   OK     The packet has been processed  and can be deleted
+ *  -EAGAIN There is a matching connection, but could not dispatch the packet
+ *          yet.  Useful when a packet arrives before a recv call is in
+ *          place.
+ *
+ * Assumptions:
+ *   The network is locked.
+ *
+ ****************************************************************************/
+
+int can_input(struct net_driver_s *dev)
+{
+  FAR struct can_conn_s *conn;
+  int ret = OK;
+
+  conn = can_nextconn(NULL); //FIXME 
+  if (conn)
+    {
+      uint16_t flags;
+
+      /* Setup for the application callback */
+
+      dev->d_appdata = dev->d_buf;
+      dev->d_sndlen  = 0;
+
+      /* Perform the application callback */
+
+      flags = can_callback(dev, conn, CAN_NEWDATA);
+
+      /* If the operation was successful, the CAN_NEWDATA flag is removed
+       * and thus the packet can be deleted (OK will be returned).
+       */
+
+      if ((flags & CAN_NEWDATA) != 0)
+        {
+          /* No.. the packet was not processed now.  Return -EAGAIN so
+           * that the driver may retry again later.  We still need to
+           * set d_len to zero so that the driver is aware that there
+           * is nothing to be sent.
+           */
+
+           nwarn("WARNING: Packet not processed\n");
+           ret = -EAGAIN;
+        }
+    }
+  else
+    {
+      ninfo("No CAN listener\n");
+    }
+
+  return ret;
+}
+
+#endif /* CONFIG_NET && CONFIG_NET_CAN */
diff --git a/net/can/can_recvfrom.c b/net/can/can_recvfrom.c
new file mode 100644
index 0000000..4062ed3
--- /dev/null
+++ b/net/can/can_recvfrom.c
@@ -0,0 +1,354 @@
+/****************************************************************************
+ * net/can/can_recvfrom.c
+ *
+ *   Copyright (C) 2007-2009, 2011-2017, 2020 Gregory Nutt. All rights
+ *     reserved.
+ *   Author: Gregory Nutt <gn...@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#ifdef CONFIG_NET_CAN
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+#include <debug.h>
+#include <assert.h>
+
+#include <arch/irq.h>
+
+#include <nuttx/semaphore.h>
+#include <nuttx/net/net.h>
+#include <nuttx/net/netdev.h>
+
+#include "netdev/netdev.h"
+#include "devif/devif.h"
+#include "can/can.h"
+#include "socket/socket.h"
+#include <netpacket/packet.h>
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct can_recvfrom_s
+{
+  FAR struct devif_callback_s *pr_cb;  /* Reference to callback instance */
+  sem_t        pr_sem;                 /* Semaphore signals recv completion */
+  size_t       pr_buflen;              /* Length of receive buffer */
+  FAR uint8_t *pr_buffer;              /* Pointer to receive buffer */
+  ssize_t      pr_recvlen;             /* The received length */
+  int          pr_result;              /* Success:OK, failure:negated errno */
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: can_add_recvlen
+ *
+ * Description:
+ *   Update information about space available for new data and update size
+ *   of data in buffer,  This logic accounts for the case where
+ *   recvfrom_udpreadahead() sets state.pr_recvlen == -1 .
+ *
+ * Input Parameters:
+ *   pstate   recvfrom state structure
+ *   recvlen  size of new data appended to buffer
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static inline void can_add_recvlen(FAR struct can_recvfrom_s *pstate,
+                                   size_t recvlen)
+{
+  if (pstate->pr_recvlen < 0)
+    {
+      pstate->pr_recvlen = 0;
+    }
+
+  pstate->pr_recvlen += recvlen;
+  pstate->pr_buffer  += recvlen;
+  pstate->pr_buflen  -= recvlen;
+}
+
+/****************************************************************************
+ * Name: can_recvfrom_newdata
+ *
+ * Description:
+ *   Copy the read data from the packet
+ *
+ * Input Parameters:
+ *   dev      The structure of the network driver that caused the event.
+ *   pstate   recvfrom state structure
+ *
+ * Returned Value:
+ *   None.
+ *
+ * Assumptions:
+ *   The network is locked.
+ *
+ ****************************************************************************/
+
+static void can_recvfrom_newdata(FAR struct net_driver_s *dev,
+                                 FAR struct can_recvfrom_s *pstate)
+{
+  size_t recvlen;
+
+  if (dev->d_len > pstate->pr_buflen)
+    {
+      recvlen = pstate->pr_buflen;
+    }
+  else
+    {
+      recvlen = dev->d_len;
+    }
+
+  /* Copy the new packet data into the user buffer */
+
+  memcpy(pstate->pr_buffer, dev->d_buf, recvlen);
+  //ninfo("Received %d bytes (of %d)\n", (int)recvlen, (int)dev->d_len);
+
+  /* Update the accumulated size of the data read */
+
+  can_add_recvlen(pstate, recvlen);
+}
+
+static uint16_t can_recvfrom_eventhandler(FAR struct net_driver_s *dev,
+                                          FAR void *pvconn,
+                                          FAR void *pvpriv, uint16_t flags)
+{
+  struct can_recvfrom_s *pstate = (struct can_recvfrom_s *)pvpriv;
+
+  //ninfo("flags: %04x\n", flags);
+
+  /* 'priv' might be null in some race conditions (?) */
+
+  if (pstate)
+    {
+      /* If a new packet is available, then complete the read action. */
+
+      if ((flags & CAN_NEWDATA) != 0)
+        {
+          /* Copy the packet */
+
+          can_recvfrom_newdata(dev, pstate);
+
+          /* We are finished. */
+
+          //ninfo("CAN done\n");
+
+          /* Don't allow any further call backs. */
+
+          pstate->pr_cb->flags   = 0;
+          pstate->pr_cb->priv    = NULL;
+          pstate->pr_cb->event   = NULL;
+
+          /* Save the sender's address in the caller's 'from' location */
+
+          //pkt_recvfrom_sender(dev, pstate);
+
+          /* indicate that the data has been consumed */
+
+          flags &= ~CAN_NEWDATA;
+
+          /* Wake up the waiting thread, returning the number of bytes
+           * actually read.
+           */
+
+          nxsem_post(&pstate->pr_sem);
+        }
+    }
+
+  return flags;
+}
+
+/****************************************************************************
+ * Name: can_recvfrom_result
+ *
+ * Description:
+ *   Evaluate the result of the recv operations
+ *
+ * Input Parameters:
+ *   result   The result of the net_lockedwait operation (may indicate EINTR)
+ *   pstate   A pointer to the state structure to be initialized
+ *
+ * Returned Value:
+ *   The result of the recv operation with errno set appropriately
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static ssize_t can_recvfrom_result(int result,
+                                   FAR struct can_recvfrom_s *pstate)
+{
+  /* Check for a error/timeout detected by the event handler.  Errors are
+   * signaled by negative errno values for the rcv length
+   */
+
+  if (pstate->pr_result < 0)
+    {
+      /* This might return EAGAIN on a timeout or ENOTCONN on loss of
+       * connection (TCP only)
+       */
+
+      return pstate->pr_result;
+    }
+
+  /* If net_lockedwait failed, then we were probably reawakened by a signal.
+   * In this case, net_lockedwait will have returned negated errno
+   * appropriately.
+   */
+
+  if (result < 0)
+    {
+      return result;
+    }
+
+  return pstate->pr_recvlen;
+}
+
+/****************************************************************************
+ * Name: can_recvfrom
+ *
+ * Description:
+ *   recvfrom() receives messages from a socket, and may be used to receive
+ *   data on a socket whether or not it is connection-oriented.
+ *
+ *   If from is not NULL, and the underlying protocol provides the source
+ *   address, this source address is filled in. The argument 'fromlen'
+ *   initialized to the size of the buffer associated with from, and modified
+ *   on return to indicate the actual size of the address stored there.
+ *
+ * Input Parameters:
+ *   psock    A pointer to a NuttX-specific, internal socket structure
+ *   buf      Buffer to receive data
+ *   len      Length of buffer
+ *   flags    Receive flags (ignored)
+ *   from     Address of source (may be NULL)
+ *   fromlen  The length of the address structure
+ *
+ ****************************************************************************/
+
+ssize_t can_recvfrom(FAR struct socket *psock, FAR void *buf,
+                                size_t len, int flags,
+                                FAR struct sockaddr *from,
+                                FAR socklen_t *fromlen)
+{
+  FAR struct can_conn_s *conn;
+  FAR struct net_driver_s *dev;
+  struct can_recvfrom_s state;
+  int ret;
+
+  DEBUGASSERT(psock != NULL && psock->s_conn != NULL && buf != NULL);
+  DEBUGASSERT(from == NULL ||
+              (fromlen != NULL && *fromlen >= sizeof(struct sockaddr_can)));
+
+  conn = (FAR struct can_conn_s *)psock->s_conn;
+  
+  if (psock->s_type != SOCK_RAW)
+    {
+      nerr("ERROR: Unsupported socket type: %d\n", psock->s_type);
+      ret = -ENOSYS;
+    }
+  
+  
+  net_lock();
+  
+  /* Initialize the state structure. */
+
+  memset(&state, 0, sizeof(struct can_recvfrom_s));
+
+  /* This semaphore is used for signaling and, hence, should not have
+   * priority inheritance enabled.
+   */
+
+  nxsem_init(&state.pr_sem, 0, 0); /* Doesn't really fail */
+  nxsem_setprotocol(&state.pr_sem, SEM_PRIO_NONE);
+
+  state.pr_buflen = len;
+  state.pr_buffer = buf;
+  
+  /* Get the device driver that will service this transfer */
+
+  dev  = conn->dev;
+  if (dev == NULL)
+    {
+      ret = -ENODEV;
+      goto errout_with_state;
+    }
+    
+    /* Set up the callback in the connection */
+
+  state.pr_cb = can_callback_alloc(dev, conn);
+  if (state.pr_cb)
+    {
+      state.pr_cb->flags  = (CAN_NEWDATA | CAN_POLL);
+      state.pr_cb->priv   = (FAR void *)&state;
+      state.pr_cb->event  = can_recvfrom_eventhandler;
+
+      /* Wait for either the receive to complete or for an error/timeout to
+       * occur. NOTES:  (1) net_lockedwait will also terminate if a signal
+       * is received, (2) the network is locked!  It will be un-locked while
+       * the task sleeps and automatically re-locked when the task restarts.
+       */
+
+      ret = net_lockedwait(&state.pr_sem);
+
+      /* Make sure that no further events are processed */
+
+      can_callback_free(dev, conn, state.pr_cb);
+      ret = can_recvfrom_result(ret, &state);
+    }
+  else
+    {
+      ret = -EBUSY;
+    }
+
+  
+errout_with_state:
+  net_unlock();
+  nxsem_destroy(&state.pr_sem);
+  return ret;
+}
+
+#endif /* CONFIG_NET_CAN */
diff --git a/net/can/can_sockif.c b/net/can/can_sockif.c
index 1de95d9..0cd389a 100644
--- a/net/can/can_sockif.c
+++ b/net/can/can_sockif.c
@@ -69,9 +69,6 @@ static ssize_t can_send(FAR struct socket *psock,
 static ssize_t can_sendto(FAR struct socket *psock, FAR const void *buf,
               size_t len, int flags, FAR const struct sockaddr *to,
               socklen_t tolen);
-static ssize_t can_recvfrom(FAR struct socket *psock, FAR void *buf,
-              size_t len, int flags, FAR struct sockaddr *from,
-              FAR socklen_t *fromlen);
 static int can_close(FAR struct socket *psock);
 
 /****************************************************************************
@@ -99,12 +96,13 @@ const struct sock_intf_s g_can_sockif =
   can_close         /* si_close */
 };
 
+
 /****************************************************************************
  * Private Functions
  ****************************************************************************/
 
 /****************************************************************************
- * Name: inet_setup
+ * Name: can_setup
  *
  * Description:
  *   Called for socket() to verify that the provided socket type and
@@ -684,55 +682,6 @@ static ssize_t can_sendto(FAR struct socket *psock, FAR const void *buf,
 }
 
 /****************************************************************************
- * Name: can_recvfrom
- *
- * Description:
- *   recvfrom() receives messages from a socket, and may be used to receive
- *   data on a socket whether or not it is connection-oriented.
- *
- *   If from is not NULL, and the underlying protocol provides the source
- *   address, this source address is filled in. The argument 'fromlen'
- *   initialized to the size of the buffer associated with from, and modified
- *   on return to indicate the actual size of the address stored there.
- *
- * Input Parameters:
- *   psock    A pointer to a NuttX-specific, internal socket structure
- *   buf      Buffer to receive data
- *   len      Length of buffer
- *   flags    Receive flags (ignored)
- *   from     Address of source (may be NULL)
- *   fromlen  The length of the address structure
- *
- ****************************************************************************/
-
-static ssize_t can_recvfrom(FAR struct socket *psock, FAR void *buf,
-                                size_t len, int flags,
-                                FAR struct sockaddr *from,
-                                FAR socklen_t *fromlen)
-{
-  FAR struct can_conn_s *conn;
-  int ret;
-
-  DEBUGASSERT(psock != NULL && psock->s_conn != NULL && buf != NULL);
-  DEBUGASSERT(from == NULL ||
-              (fromlen != NULL && *fromlen >= sizeof(struct sockaddr_can)));
-
-  conn = (FAR struct can_conn_s *)psock->s_conn;
-#warning Missing logic
-
-  switch (conn->protocol)
-    {
-#warning Missing logic
-
-      default:
-       ret = -EOPNOTSUPP;
-       break;
-    }
-
-  return ret;
-}
-
-/****************************************************************************
  * Name: can_close
  *
  * Description:
diff --git a/net/devif/Make.defs b/net/devif/Make.defs
index b2dca4a..57aac89 100644
--- a/net/devif/Make.defs
+++ b/net/devif/Make.defs
@@ -62,7 +62,11 @@ endif
 
 # Raw packet socket support
 
-ifeq ($(filter y,$(CONFIG_NET_PKT) $(CONFIG_NET_CAN)),)
+ifeq ($(CONFIG_NET_PKT),y)
+NET_CSRCS += devif_pktsend.c
+endif
+
+ifeq ($(CONFIG_NET_CAN),y)
 NET_CSRCS += devif_pktsend.c
 endif
 


[incubator-nuttx] 10/31: FlexCAN transmit CAN FD support

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch SocketCAN
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 4a3ec73e7da4c0874b7891aeecdf68331e08221f
Author: Peter van der Perk <pe...@nxp.com>
AuthorDate: Tue Feb 25 16:56:26 2020 +0100

    FlexCAN transmit CAN FD support
    
    Also checks now if TX MB is full so that transmit blocks
    Note receive performance is affect by non-optimized memcpy please use ARMV7M_MEMCPY for best performance
    Removed unused g_desc_pool
---
 arch/arm/src/s32k1xx/s32k1xx_flexcan.c | 279 ++++++++++++++++++++-------------
 net/can/can_callback.c                 |   1 +
 2 files changed, 172 insertions(+), 108 deletions(-)

diff --git a/arch/arm/src/s32k1xx/s32k1xx_flexcan.c b/arch/arm/src/s32k1xx/s32k1xx_flexcan.c
index bb0d1d0..f394a20 100644
--- a/arch/arm/src/s32k1xx/s32k1xx_flexcan.c
+++ b/arch/arm/src/s32k1xx/s32k1xx_flexcan.c
@@ -114,6 +114,8 @@
 #define CAN_FIFO_OV                 (1 << 6)
 #define CAN_FIFO_WARN               (1 << 7)
 
+#define POOL_SIZE                   1
+
 /* Interrupt flags for RX fifo */
 #define IFLAG1_RXFIFO               (CAN_FIFO_NE | CAN_FIFO_WARN | CAN_FIFO_OV)
 
@@ -236,8 +238,13 @@ struct s32k1xx_driver_s
   WDOG_ID txtimeout;           /* TX timeout timer */
   struct work_s irqwork;       /* For deferring interrupt work to the work queue */
   struct work_s pollwork;      /* For deferring poll work to the work queue */
-  struct enet_desc_s *txdesc;  /* A pointer to the list of TX descriptor */
-  struct enet_desc_s *rxdesc;  /* A pointer to the list of RX descriptors */
+#ifdef CAN_FD
+  struct canfd_frame *txdesc;  /* A pointer to the list of TX descriptor */
+  struct canfd_frame *rxdesc;  /* A pointer to the list of RX descriptors */
+#else
+  struct can_frame *txdesc;  /* A pointer to the list of TX descriptor */
+  struct can_frame *rxdesc;  /* A pointer to the list of RX descriptors */
+#endif
 
   /* This holds the information visible to the NuttX network */
 
@@ -253,8 +260,16 @@ struct s32k1xx_driver_s
 
 static struct s32k1xx_driver_s g_flexcan[CONFIG_S32K1XX_ENET_NETHIFS];
 
-static uint8_t g_desc_pool[2000]
+#ifdef CAN_FD
+static uint8_t g_tx_pool[sizeof(struct canfd_frame)*POOL_SIZE];
+static uint8_t g_rx_pool[sizeof(struct canfd_frame)*POOL_SIZE];
+#else
+static uint8_t g_tx_pool[sizeof(struct can_frame)*POOL_SIZE]
+               __attribute__((aligned(ARMV7M_DCACHE_LINESIZE)));
+static uint8_t g_rx_pool[sizeof(struct can_frame)*POOL_SIZE]
                __attribute__((aligned(ARMV7M_DCACHE_LINESIZE)));
+#endif
+
 
 /****************************************************************************
  * Private Function Prototypes
@@ -368,16 +383,17 @@ static void s32k1xx_reset(struct s32k1xx_driver_s *priv);
 
 static bool s32k1xx_txringfull(FAR struct s32k1xx_driver_s *priv)
 {
-  uint8_t txnext;
-
-  /* Check if there is room in the hardware to hold another outgoing
-   * packet.  The ring is full if incrementing the head pointer would
-   * collide with the tail pointer.
-   */
-
-  txnext = priv->txhead + 1;
+  uint32_t mbi = 0;
 
-  return priv->txtail == txnext;
+  while (mbi < TXMBCOUNT)
+	{
+	  if (priv->tx[mbi].cs.code != CAN_TXMB_DATAORREMOTE)
+		{
+		  return 0;
+		}
+	  mbi++;
+	}
+  return 1;
 }
 
 /****************************************************************************
@@ -404,19 +420,6 @@ static int s32k1xx_transmit(FAR struct s32k1xx_driver_s *priv)
 {
   #warning Missing logic
 
-  struct can_frame *frame = (struct can_frame *)priv->dev.d_buf;
-
-#if 0
-  ninfo("CAN id: %i dlc: %i", frame->can_id, frame->can_dlc);
-
-  for (int i = 0; i < frame->can_dlc; i++)
-    {
-      ninfo(" %02X", frame->data[i]);
-    }
-
-  ninfo("\r\n");
-#endif
-
   /* Attempt to write frame */
 
   uint32_t mbi = 0;
@@ -456,45 +459,98 @@ static int s32k1xx_transmit(FAR struct s32k1xx_driver_s *priv)
   struct mb_s *mb = &priv->tx[mbi];
   mb->cs.code = CAN_TXMB_INACTIVE;
 
-  if (0) /* FIXME detect Std or Ext id */
-    {
-      cs.ide = 1;
-      mb->id.ext = frame->can_id & MASKEXTID;
-    }
-  else
+  if(priv->dev.d_len == sizeof(struct can_frame))
     {
-      mb->id.std = frame->can_id & MASKSTDID;
-    }
+	  struct can_frame *frame = (struct can_frame *)priv->dev.d_buf;
 
-#if 0
-  cs.rtr = frame.isRemoteTransmissionRequest();
-#endif
+	  if (0) /* FIXME detect Std or Ext id */
+	    {
+	      cs.ide = 1;
+	      mb->id.ext = frame->can_id & MASKEXTID;
+	    }
+	  else
+	    {
+	      mb->id.std = frame->can_id & MASKSTDID;
+	    }
 
-  cs.dlc = frame->can_dlc;
+	#if 0
+	  cs.rtr = frame.isRemoteTransmissionRequest();
+	#endif
 
-  /* FIXME endian swap instruction or somekind takes 1.5us right now */
+	  cs.dlc = frame->can_dlc;
 
-  mb->data[0].b00 = frame->data[0];
-  mb->data[0].b01 = frame->data[1];
-  mb->data[0].b02 = frame->data[2];
-  mb->data[0].b03 = frame->data[3];
-  mb->data[1].b00 = frame->data[4];
-  mb->data[1].b01 = frame->data[5];
-  mb->data[1].b02 = frame->data[6];
-  mb->data[1].b03 = frame->data[7];
+	  mb->data[0].w00 = __builtin_bswap32(*(uint32_t*)&frame->data[0]);
+	  mb->data[1].w00 = __builtin_bswap32(*(uint32_t*)&frame->data[4]);
 
-#if 0
-  /* Registering the pending transmission so we can track its deadline and
-   * loopback it as needed
-   */
+    }
+  else /* CAN FD frame */
+    {
+  	  struct canfd_frame *frame = (struct canfd_frame *)priv->dev.d_buf;
+
+  	  cs.edl = 1; /* CAN FD Frame */
+
+  	  if (0) /* FIXME detect Std or Ext id */
+  	    {
+  	      cs.ide = 1;
+  	      mb->id.ext = frame->can_id & MASKEXTID;
+  	    }
+  	  else
+  	    {
+  	      mb->id.std = frame->can_id & MASKSTDID;
+  	    }
+
+  	#if 0
+  	  cs.rtr = frame.isRemoteTransmissionRequest();
+  	#endif
+
+  	  if(frame->len < 9)
+  	    {
+  		  cs.dlc = frame->len;
+  	    }
+  	  else
+  	    {
+  	      if (frame->len < 13)
+  	        {
+			  cs.dlc = 9;
+  	        }
+  	      else if (frame->len < 17)
+  	        {
+			   cs.dlc = 10;
+  	        }
+  	      else if (frame->len < 21)
+  	        {
+			   cs.dlc = 11;
+  	        }
+  	      else if (frame->len < 25)
+  	        {
+			   cs.dlc = 12;
+  	        }
+  	      else if (frame->len < 33)
+  	        {
+			   cs.dlc = 13;
+  	        }
+  	      else if (frame->len < 49)
+  	        {
+			   cs.dlc = 14;
+  	        }
+  	      else if (frame->len < 65)
+  	        {
+			   cs.dlc = 15;
+  	        }
+  	      else
+  	        {
+  	    	   cs.dlc = 15; /* FIXME check CAN FD spec */
+  	        }
+  	    }
+
+  	  uint32_t* frame_data_word = (uint32_t*)&frame->data[0];
+
+	  for(int i = 0; i < (frame->len + 4 - 1) / 4; i++)
+		{
+	  	  mb->data[i].w00 = __builtin_bswap32(frame_data_word[i]);
+		}
+    }
 
-  txitem& txi        = pending_tx_[mbi];
-  txi.deadline       = tx_deadline;
-  txi.frame          = frame;
-  txi.loopback       = (flags & uavcan::CanIOFlagLoopback) != 0;
-  txi.abort_on_error = (flags & uavcan::CanIOFlagAbortOnError) != 0;
-  txi.pending        = txitem::busy;
-#endif
 
   s32k1xx_gpiowrite(PIN_PORTD | PIN31, 0);
 
@@ -552,6 +608,7 @@ static int s32k1xx_txpoll(struct net_driver_s *dev)
 
           s32k1xx_transmit(priv);
 #if 0
+          //FIXME implement ring buffer and increment pointer just like the enet driver??
           priv->dev.d_buf =
             (uint8_t *)s32k1xx_swap32((uint32_t)priv->txdesc[priv->txhead].data);
 #endif
@@ -633,138 +690,127 @@ static void s32k1xx_receive(FAR struct s32k1xx_driver_s *priv, uint32_t flags)
 
       if(rf->cs.edl) /* CAN FD frame */
         {
-
-    	  struct canfd_frame frame;
+    	  struct canfd_frame* frame = priv->rxdesc;
 
           if (rf->cs.ide)
             {
-              frame.can_id = MASKEXTID & rf->id.ext;
-              frame.can_id |= FLAGEFF;
+              frame->can_id = MASKEXTID & rf->id.ext;
+              frame->can_id |= FLAGEFF;
             }
           else
             {
-              frame.can_id = MASKSTDID & rf->id.std;
+              frame->can_id = MASKSTDID & rf->id.std;
             }
 
           if (rf->cs.rtr)
             {
-              frame.can_id |= FLAGRTR;
+              frame->can_id |= FLAGRTR;
             }
 
           if(rf->cs.dlc < 9){
-              frame.len = rf->cs.dlc;
+              frame->len = rf->cs.dlc;
           } else {
         	  switch(rf->cs.dlc)
         	    {
         	     case 9:
-        	       frame.len = 12;
+        	       frame->len = 12;
         	       break;
 
         	     case 10:
-        	       frame.len = 16;
+        	       frame->len = 16;
         	       break;
 
         	     case 11:
-        	       frame.len = 20;
+        	       frame->len = 20;
         	       break;
 
         	     case 12:
-        	       frame.len = 24;
+        	       frame->len = 24;
         	       break;
 
         	     case 13:
-        	       frame.len = 32;
+        	       frame->len = 32;
         	       break;
 
         	     case 14:
-        	       frame.len = 48;
+        	       frame->len = 48;
         	       break;
 
         	     case 15:
-        	       frame.len = 64;
+        	       frame->len = 64;
         	       break;
         	    }
           }
 
-    	  int j = 0;
-          for(int i = 0; i < (frame.len + 4 - 1) / 4; i++)
+    	  uint32_t* frame_data_word = (uint32_t*)&frame->data[0];
+
+          for(int i = 0; i < (frame->len + 4 - 1) / 4; i++)
             {
-              frame.data[0+j] = rf->data[i].b00;
-              frame.data[1+j] = rf->data[i].b01;
-              frame.data[2+j] = rf->data[i].b02;
-              frame.data[3+j] = rf->data[i].b03;
-              j = j + 4;
+        	  frame_data_word[i] = __builtin_bswap32(rf->data[i].w00);
             }
 
           /* Clear MB interrupt flag */
           regval  = getreg32(S32K1XX_CAN0_IFLAG1);
-          regval |= (1 << mb_index);
+          regval |= (0x80000000 >> mb_index);
           putreg32(regval, S32K1XX_CAN0_IFLAG1);
 
-          /* Copy the buffer pointer to priv->dev.d_buf.  Set amount of data
+          /* Copy the buffer pointer to priv->dev..  Set amount of data
            * in priv->dev.d_len
            */
 
           priv->dev.d_len = sizeof(struct canfd_frame);
-          priv->dev.d_buf = (uint8_t *)s32k1xx_swap32((uint32_t)&frame); /* FIXME */
+          priv->dev.d_buf = frame;
         }
       else /* CAN 2.0 Frame */
         {
-    	  struct can_frame frame;
+    	  struct can_frame* frame = priv->rxdesc;
 
           if (rf->cs.ide)
             {
-              frame.can_id = MASKEXTID & rf->id.ext;
-              frame.can_id |= FLAGEFF;
+              frame->can_id = MASKEXTID & rf->id.ext;
+              frame->can_id |= FLAGEFF;
             }
           else
             {
-              frame.can_id = MASKSTDID & rf->id.std;
+              frame->can_id = MASKSTDID & rf->id.std;
             }
 
           if (rf->cs.rtr)
             {
-              frame.can_id |= FLAGRTR;
+              frame->can_id |= FLAGRTR;
             }
 
-          frame.can_dlc = rf->cs.dlc;
+          frame->can_dlc = rf->cs.dlc;
 
-          frame.data[0] = rf->data[0].b00;
-          frame.data[1] = rf->data[0].b01;
-          frame.data[2] = rf->data[0].b02;
-          frame.data[3] = rf->data[0].b03;
-          frame.data[4] = rf->data[1].b00;
-          frame.data[5] = rf->data[1].b01;
-          frame.data[6] = rf->data[1].b02;
-          frame.data[7] = rf->data[1].b03;
+    	  *(uint32_t*)&frame->data[0] = __builtin_bswap32(rf->data[0].w00);
+    	  *(uint32_t*)&frame->data[4] = __builtin_bswap32(rf->data[1].w00);
 
           /* Clear MB interrupt flag */
           regval  = getreg32(S32K1XX_CAN0_IFLAG1);
           regval |= (1 << mb_index);
           putreg32(regval, S32K1XX_CAN0_IFLAG1);
 
-          /* Copy the buffer pointer to priv->dev.d_buf.  Set amount of data
+          /* Copy the buffer pointer to priv->dev..  Set amount of data
            * in priv->dev.d_len
            */
 
           priv->dev.d_len = sizeof(struct can_frame);
-          priv->dev.d_buf = (uint8_t *)s32k1xx_swap32((uint32_t)&frame); /* FIXME */
+          priv->dev.d_buf = frame;
         }
 
-      /* Invalidate the buffer so that the correct packet will be re-read
-       * from memory when the packet content is accessed.
-       */
-
-      up_invalidate_dcache((uintptr_t)priv->dev.d_buf,
-                      (uintptr_t)priv->dev.d_buf + priv->dev.d_len);
-
       /* Send to socket interface */
 
       NETDEV_RXPACKETS(&priv->dev);
 
       can_input(&priv->dev);
 
-      /* Store with timeout into the FIFO buffer and signal update event */
+      /* Point the packet buffer back to the next Tx buffer that will be
+       * used during the next write.  If the write queue is full, then
+       * this will point at an active buffer, which must not be written
+       * to.  This is OK because devif_poll won't be called unless the
+       * queue is not full.
+       */
+      priv->dev.d_buf = priv->txdesc;
     }
 }
 
@@ -790,6 +836,12 @@ static void s32k1xx_txdone(FAR struct s32k1xx_driver_s *priv, uint32_t flags)
 {
   #warning Missing logic
 
+  /* We are here because a transmission completed, so the watchdog can be
+   * canceled.
+   */
+
+  wd_cancel(priv->txtimeout);
+
   /* FIXME process aborts */
 
   /* Process TX completions */
@@ -805,10 +857,18 @@ static void s32k1xx_txdone(FAR struct s32k1xx_driver_s *priv, uint32_t flags)
           const bool txok = priv->tx[mbi].cs.code != CAN_TXMB_ABORT;
           handleTxMailboxInterrupt(mbi, txok, utc_usec);
 #endif
+
+          NETDEV_TXDONE(&priv->dev);
         }
 
       mb_bit <<= 1;
     }
+
+  /* There should be space for a new TX in any event.  Poll the network for
+   * new XMIT data
+   */
+
+  devif_poll(&priv->dev, s32k1xx_txpoll);
 }
 
 /****************************************************************************
@@ -950,7 +1010,7 @@ static void s32k1xx_poll_work(FAR void *arg)
    */
 
   net_lock();
-  if (1) /* !s32k1xx_txringfull(priv)) */
+  if (!s32k1xx_txringfull(priv))
     {
       /* If so, update TCP timing states and poll the network for new XMIT
        * data. Hmmm.. might be bug here.  Does this mean if there is a
@@ -1096,7 +1156,10 @@ static int s32k1xx_ifup(struct net_driver_s *dev)
 
   priv->bifup = true;
 
-  priv->dev.d_buf = &g_desc_pool;
+  priv->txdesc = &g_tx_pool;
+  priv->rxdesc = &g_rx_pool;
+
+  priv->dev.d_buf = priv->txdesc;
 
   /* Set interrupts */
 
@@ -1461,7 +1524,7 @@ static void s32k1xx_reset(struct s32k1xx_driver_s *priv)
             (((TOTALMBCOUNT - 1) << CAN_MCR_MAXMB_SHIFT) & CAN_MCR_MAXMB_MASK);
   putreg32(regval, S32K1XX_CAN0_MCR);
 
-  regval  = CAN_CTRL2_RRS | CAN_CTRL2_EACEN | CAN_CTRL2_RFFN_16MB; /* FIXME TASD */
+  regval  = CAN_CTRL2_RRS | CAN_CTRL2_EACEN; /* FIXME TASD */
   putreg32(regval, S32K1XX_CAN0_CTRL2);
 
   for (i = 0; i < TOTALMBCOUNT; i++)
diff --git a/net/can/can_callback.c b/net/can/can_callback.c
index c61bdce..0f60b6a 100644
--- a/net/can/can_callback.c
+++ b/net/can/can_callback.c
@@ -30,6 +30,7 @@
 
 #include <nuttx/net/netconfig.h>
 #include <nuttx/net/netdev.h>
+#include <nuttx/mm/iob.h>
 
 #include "devif/devif.h"
 #include "can/can.h"


[incubator-nuttx] 15/31: Added functional support for CAN_RAW_FILTER sockopt

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch SocketCAN
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit c83f005e09e73ff4cdc6f369a636cbeda6468b70
Author: Peter van der Perk <pe...@nxp.com>
AuthorDate: Mon Mar 9 12:47:26 2020 +0100

    Added functional support for CAN_RAW_FILTER sockopt
---
 include/nuttx/can.h      |  1 -
 net/can/Kconfig          |  7 +++++++
 net/can/can.h            |  2 ++
 net/can/can_conn.c       | 17 +++++++++++++++++
 net/can/can_getsockopt.c | 27 ++++++++++++++++++++-------
 net/can/can_input.c      |  2 +-
 net/can/can_recvfrom.c   | 47 ++++++++++++++++++++++++++++++++++++++---------
 net/can/can_setsockopt.c | 22 +++++++++++++++++-----
 8 files changed, 102 insertions(+), 23 deletions(-)

diff --git a/include/nuttx/can.h b/include/nuttx/can.h
index 7a66a65..c681b32 100644
--- a/include/nuttx/can.h
+++ b/include/nuttx/can.h
@@ -214,7 +214,6 @@
 #define CANFD_ESI 0x02 /* error state indicator of the transmitting node */
 
 #define CAN_INV_FILTER     0x20000000U /* to be set in can_filter.can_id */
-#define CAN_RAW_FILTER_MAX 512         /* maximum number of can_filter set via setsockopt() */
 
 /************************************************************************************
  * Public Types
diff --git a/net/can/Kconfig b/net/can/Kconfig
index d5b6dbd..3b2e450 100644
--- a/net/can/Kconfig
+++ b/net/can/Kconfig
@@ -31,6 +31,13 @@ config NET_CAN_SOCK_OPTS
 	---help---
 		Enable support for the CAN socket options
 		
+config NET_CAN_RAW_FILTER_MAX
+	int "CAN_RAW_FILTER max filter count"
+	default 32
+	depends on NET_CAN_SOCK_OPTS
+	---help---
+		Maximum number of CAN_RAW filters that can be set per CAN connection.
+		
 config NET_CAN_NOTIFIER
 	bool "Support CAN notifications"
 	default n
diff --git a/net/can/can.h b/net/can/can.h
index 5992deb..e5d45f0 100644
--- a/net/can/can.h
+++ b/net/can/can.h
@@ -109,6 +109,8 @@ struct can_conn_s
   int32_t loopback;
   int32_t recv_own_msgs;
   int32_t fd_frames;
+  struct can_filter filters[CONFIG_NET_CAN_RAW_FILTER_MAX];
+  int32_t filter_count;
   
   /* TODO add filter support */
 #endif
diff --git a/net/can/can_conn.c b/net/can/can_conn.c
index 21622b5..74f2d9b 100644
--- a/net/can/can_conn.c
+++ b/net/can/can_conn.c
@@ -142,6 +142,23 @@ FAR struct can_conn_s *can_alloc(void)
       /* FIXME SocketCAN default behavior enables loopback */
       
 
+#ifdef CONFIG_NET_CANPROTO_OPTIONS
+      /* By default the filter is configured to catch all,
+       * this is done in commented filter code below:
+       *
+       * struct can_filter_t catchall_filter;
+       * filter.can_id = 0;
+       * filter.can_mask = 0;
+       * conn->filters[0] = catchall_filter;
+       *
+       * However memset already sets the filter to 0
+       * therefore we only have to set the filter count to 1
+       */
+
+      conn->filter_count = 1;
+#endif
+
+
       /* Enqueue the connection into the active list */
 
       dq_addlast(&conn->node, &g_active_can_connections);
diff --git a/net/can/can_getsockopt.c b/net/can/can_getsockopt.c
index 91720ad..e4149b6 100644
--- a/net/can/can_getsockopt.c
+++ b/net/can/can_getsockopt.c
@@ -98,16 +98,29 @@ int can_getsockopt(FAR struct socket *psock, int option,
           {
             ret = -EINVAL;
           }
-
-        if (value_len > CAN_RAW_FILTER_MAX * sizeof(struct can_filter))
+        else if (*value_len > CONFIG_NET_CAN_RAW_FILTER_MAX * sizeof(struct can_filter))
           {
             ret = -EINVAL;
           }
-
-        count = *value_len / sizeof(struct can_filter);
-
-        /* FIXME pass filter to driver */
-
+        else
+          {
+            int count = conn->filter_count;
+
+        	if (*value_len < count * sizeof(struct can_filter))
+              {
+                count = *value_len / sizeof(struct can_filter);
+              }
+        	else
+        	  {
+        	    *value_len = count * sizeof(struct can_filter);
+        	  }
+
+            for(int i = 0; i < count; i++)
+              {
+            	((struct can_filter *)value)[i] = conn->filters[i];
+              }
+            ret = OK;
+          }
         break;
 
       case CAN_RAW_ERR_FILTER:
diff --git a/net/can/can_input.c b/net/can/can_input.c
index 30e2507..52d6c50 100644
--- a/net/can/can_input.c
+++ b/net/can/can_input.c
@@ -64,7 +64,7 @@ int can_input(struct net_driver_s *dev)
   FAR struct can_conn_s *conn;
   int ret = OK;
 
-  conn = can_nextconn(NULL); /* FIXME  */
+  conn = can_nextconn(NULL); /* FIXME Support for multiple sockets??? */
   if (conn)
     {
       uint16_t flags;
diff --git a/net/can/can_recvfrom.c b/net/can/can_recvfrom.c
index c23af93..06b133c 100644
--- a/net/can/can_recvfrom.c
+++ b/net/can/can_recvfrom.c
@@ -294,6 +294,33 @@ static inline int can_readahead(struct can_recvfrom_s *pstate)
   return 0;
 }
 
+#ifdef CONFIG_NET_CANPROTO_OPTIONS
+static int can_recv_filter(struct can_conn_s *conn, canid_t id)
+{
+  for(int i = 0; i < conn->filter_count; i++)
+    {
+	  if (conn->filters[i].can_id & CAN_INV_FILTER)
+	    {
+		  if((id & conn->filters[i].can_mask) !=
+				  ((conn->filters[i].can_id & ~CAN_INV_FILTER)
+						  & conn->filters[i].can_mask))
+		    {
+			  return 1;
+		    }
+	    }
+	  else
+	    {
+		  if((id & conn->filters[i].can_mask) ==
+				  (conn->filters[i].can_id & conn->filters[i].can_mask))
+		    {
+			  return 1;
+		    }
+	    }
+    }
+  return 0;
+}
+#endif
+
 static uint16_t can_recvfrom_eventhandler(FAR struct net_driver_s *dev,
                                           FAR void *pvconn,
                                           FAR void *pvpriv, uint16_t flags)
@@ -305,14 +332,22 @@ static uint16_t can_recvfrom_eventhandler(FAR struct net_driver_s *dev,
 
   if (pstate)
     {
-      /* If a new packet is available, then complete the read action. */
-
       if ((flags & CAN_NEWDATA) != 0)
         {
+    	  /* If a new packet is available, check receive filters
+    	   * when is valid then complete the read action. */
+#ifdef CONFIG_NET_CANPROTO_OPTIONS
+    	  if(can_recv_filter(conn,(canid_t)*dev->d_appdata) == 0)
+    	    {
+    		  flags &= ~CAN_NEWDATA;
+    	  	  return flags;
+    		}
+#endif
+
     	  /* do not pass frames with DLC > 8 to a legacy socket */
     	  if (!conn->fd_frames)
     	    {
-    		  struct canfd_frame *cfd = (struct canfd_frame *)dev->d_appdata;
+    		  struct canfd_frame *cfd = (struct canfd_frame*)dev->d_appdata;
     	      if (cfd->len > CAN_MAX_DLEN)
     	      {
     	    	/* DO WE NEED TO CLEAR FLAGS?? */
@@ -333,12 +368,6 @@ static uint16_t can_recvfrom_eventhandler(FAR struct net_driver_s *dev,
           pstate->pr_cb->priv    = NULL;
           pstate->pr_cb->event   = NULL;
 
-#if 0
-          /* Save the sender's address in the caller's 'from' location */
-
-          pkt_recvfrom_sender(dev, pstate);
-#endif
-
           /* indicate that the data has been consumed */
 
           flags &= ~CAN_NEWDATA;
diff --git a/net/can/can_setsockopt.c b/net/can/can_setsockopt.c
index 3bad6e0..659d84b 100644
--- a/net/can/can_setsockopt.c
+++ b/net/can/can_setsockopt.c
@@ -88,20 +88,32 @@ int can_setsockopt(FAR struct socket *psock, int option,
   switch (option)
     {
       case CAN_RAW_FILTER:
-        if (value_len % sizeof(struct can_filter) != 0)
+    	if (value_len == 0)
+    	  {
+    		conn->filter_count = 0;
+    	    ret = OK;
+    	  }
+    	else if (value_len % sizeof(struct can_filter) != 0)
           {
             ret = -EINVAL;
           }
-
-        if (value_len > CAN_RAW_FILTER_MAX * sizeof(struct can_filter))
+        else if (value_len > CONFIG_NET_CAN_RAW_FILTER_MAX * sizeof(struct can_filter))
           {
             ret = -EINVAL;
           }
+        else
+          {
+		    count = value_len / sizeof(struct can_filter);
 
-        count = value_len / sizeof(struct can_filter);
+		    for(int i = 0; i < count; i++)
+		      {
+				conn->filters[i] = ((struct can_filter *)value)[i];
+		      }
 
-        /* FIXME pass filter to driver */
+		    conn->filter_count = count;
 
+            ret = OK;
+          }
         break;
 
       case CAN_RAW_ERR_FILTER:


[incubator-nuttx] 19/31: Added support for SO_TIMESTAMP in socketlayer and SocketCAN Cleanup FlexCAN driver driver Disabled workqueue based TX in FlexCAN

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch SocketCAN
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 4bfb16f7bc2722cf39ca961d272ddc2a52ae38f2
Author: Peter van der Perk <pe...@nxp.com>
AuthorDate: Wed Mar 11 16:13:18 2020 +0100

    Added support for SO_TIMESTAMP in socketlayer and SocketCAN
        Cleanup FlexCAN driver driver
        Disabled workqueue based TX in FlexCAN
---
 arch/arm/src/s32k1xx/s32k1xx_flexcan.c | 228 +++++------------------------
 include/nuttx/net/net.h                |   7 +
 libs/libc/net/lib_recvmsg.c            |   4 +-
 net/bluetooth/bluetooth_sockif.c       |   3 +
 net/can/can.h                          |  28 ++++
 net/can/can_callback.c                 |  16 +++
 net/can/can_recvfrom.c                 | 252 +++++++++++++++++++++++++++++++++
 net/can/can_sockif.c                   |  10 +-
 net/icmp/icmp_sockif.c                 |   3 +
 net/icmpv6/icmpv6_sockif.c             |   3 +
 net/ieee802154/ieee802154_sockif.c     |   3 +
 net/inet/inet_sockif.c                 |   3 +
 net/local/local_sockif.c               |   3 +
 net/netlink/netlink_sockif.c           |   3 +
 net/pkt/pkt_sockif.c                   |   3 +
 net/socket/Kconfig                     |  16 +++
 net/socket/Make.defs                   |   5 +
 net/socket/getsockopt.c                |  13 ++
 net/socket/setsockopt.c                |  24 ++++
 net/socket/socket.h                    |   2 +-
 20 files changed, 430 insertions(+), 199 deletions(-)

diff --git a/arch/arm/src/s32k1xx/s32k1xx_flexcan.c b/arch/arm/src/s32k1xx/s32k1xx_flexcan.c
index 2e73dc9..8e79833 100644
--- a/arch/arm/src/s32k1xx/s32k1xx_flexcan.c
+++ b/arch/arm/src/s32k1xx/s32k1xx_flexcan.c
@@ -59,9 +59,14 @@
  * is required.
  */
 
+
+/* FIXME A workqueue is required for enet but for FLEXCAN it increased the
+ * transmit latency by ~ 40us from 24 to 67us
+ * Therefore for now its configurable by the WORK_QUEUE define
+ * If we know for sure that a workqueue isn't required
+ * Then all WORK_QUEUE related code will be removed */
 #if !defined(CONFIG_SCHED_WORKQUEUE)
-#  error Work queue support is required
-   //FIXME maybe for enet not sure for FLEXCAN
+//#  error Work queue support is required
 #else
 
   /* Select work queue.  Always use the LP work queue if available.  If not,
@@ -72,28 +77,14 @@
    * processing that never suspends.  Suspending the high priority work queue
    * may bring the system to its knees!
    */
-
-#  define ETHWORK LPWORK
+//#  define WORK_QUEUE
+#  define CANWORK LPWORK
 #endif
 
 /* CONFIG_S32K1XX_FLEXCAN_NETHIFS determines the number of physical interfaces
  * that will be supported.
  */
 
-#if 0
-#if CONFIG_S32K1XX_FLEXCAN_NETHIFS != 1
-#  error "CONFIG_S32K1XX_FLEXCAN_NETHIFS must be one for now"
-#endif
-
-#if CONFIG_S32K1XX_FLEXCAN_NTXBUFFERS < 1
-#  error "Need at least one TX buffer"
-#endif
-
-#if CONFIG_S32K1XX_FLEXCAN_NRXBUFFERS < 1
-#  error "Need at least one RX buffer"
-#endif
-#endif
-
 #define MASKSTDID                   0x000007ff
 #define MASKEXTID                   0x1fffffff
 #define FLAGEFF                     (1 << 31) /* Extended frame format */
@@ -122,45 +113,13 @@
 
 static int peak_tx_mailbox_index_ = 0;
 
-/* Normally you would clean the cache after writing new values to the DMA
- * memory so assure that the dirty cache lines are flushed to memory
- * before the DMA occurs.  And you would invalid the cache after a data is
- * received via DMA so that you fetch the actual content of the data from
- * the cache.
- *
- * These conditions are not fully supported here.  If the write-throuch
- * D-Cache is enabled, however, then many of these issues go away:  The
- * cache clean operation does nothing (because there are not dirty cache
- * lines) and the cache invalid operation is innocuous (because there are
- * never dirty cache lines to be lost; valid data will always be reloaded).
- *
- * At present, we simply insist that write through cache be enabled.
- */
-
-#if defined(CONFIG_ARMV7M_DCACHE) && !defined(CONFIG_ARMV7M_DCACHE_WRITETHROUGH)
-#  error Write back D-Cache not yet supported
-#endif
-
+#ifdef WORK_QUEUE
 /* TX poll delay = 1 seconds. CLK_TCK is the number of clock ticks per
  * second.
  */
 
 #define S32K1XX_WDDELAY     (1*CLK_TCK)
-
-/* Align assuming that the D-Cache is enabled (probably 32-bytes).
- *
- * REVISIT: The size of descriptors and buffers must also be in even units
- * of the cache line size  That is because the operations to clean and
- * invalidate the cache will operate on a full 32-byte cache line.  If
- * CONFIG_FLEXCAN_ENHANCEDBD is selected, then the size of the descriptor is
- * 32-bytes (and probably already the correct size for the cache line);
- * otherwise, the size of the descriptors much smaller, only 8 bytes.
- */
-
-#define FLEXCAN_ALIGN        ARMV7M_DCACHE_LINESIZE
-#define FLEXCAN_ALIGN_MASK   (FLEXCAN_ALIGN - 1)
-#define FLEXCAN_ALIGN_UP(n)  (((n) + FLEXCAN_ALIGN_MASK) & ~FLEXCAN_ALIGN_MASK)
-
+#endif
 
 /****************************************************************************
  * Private Types
@@ -235,8 +194,10 @@ struct s32k1xx_driver_s
   uint8_t txhead;              /* The next TX descriptor to use */
   uint8_t rxtail;              /* The next RX descriptor to use */
   uint8_t phyaddr;             /* Selected PHY address */
+#ifdef WORK_QUEUE
   WDOG_ID txpoll;              /* TX poll timer */
   WDOG_ID txtimeout;           /* TX timeout timer */
+#endif
   struct work_s irqwork;       /* For deferring interrupt work to the work queue */
   struct work_s pollwork;      /* For deferring poll work to the work queue */
 #ifdef CAN_FD
@@ -276,21 +237,6 @@ static uint8_t g_rx_pool[sizeof(struct can_frame)*POOL_SIZE]
  * Private Function Prototypes
  ****************************************************************************/
 
-/* Utility functions */
-
-#ifndef S32K1XX_BUFFERS_SWAP
-#  define s32k1xx_swap32(value) (value)
-#  define s32k1xx_swap16(value) (value)
-#else
-#if 0 /* Use builtins if the compiler supports them */
-static inline uint32_t s32k1xx_swap32(uint32_t value);
-static inline uint16_t s32k1xx_swap16(uint16_t value);
-#else
-#  define s32k1xx_swap32 __builtin_bswap32
-#  define s32k1xx_swap16 __builtin_bswap16
-#endif
-#endif
-
 /****************************************************************************
  * Name: arm_clz
  *
@@ -328,21 +274,17 @@ static uint32_t s32k1xx_waitmcr_change(uint32_t mask,
 
 /* Interrupt handling */
 
-static void s32k1xx_dispatch(FAR struct s32k1xx_driver_s *priv);
 static void s32k1xx_receive(FAR struct s32k1xx_driver_s *priv, uint32_t flags);
 static void s32k1xx_txdone(FAR struct s32k1xx_driver_s *priv, uint32_t flags);
 
-static void s32k1xx_flexcan_interrupt_work(FAR void *arg);
 static int  s32k1xx_flexcan_interrupt(int irq, FAR void *context,
                                       FAR void *arg);
 
 /* Watchdog timer expirations */
-
-static void s32k1xx_txtimeout_work(FAR void *arg);
-static void s32k1xx_txtimeout_expiry(int argc, uint32_t arg, ...);
-
+#ifdef WORK_QUEUE
 static void s32k1xx_poll_work(FAR void *arg);
 static void s32k1xx_polltimer_expiry(int argc, uint32_t arg, ...);
+#endif
 
 /* NuttX callback functions */
 
@@ -359,7 +301,6 @@ static int  s32k1xx_ioctl(struct net_driver_s *dev, int cmd,
 
 /* Initialization */
 
-static void s32k1xx_initbuffers(struct s32k1xx_driver_s *priv);
 static int  s32k1xx_initialize(struct s32k1xx_driver_s *priv);
 static void s32k1xx_reset(struct s32k1xx_driver_s *priv);
 
@@ -632,28 +573,6 @@ static int s32k1xx_txpoll(struct net_driver_s *dev)
   return 0;
 }
 
-/****************************************************************************
- * Function: s32k1xx_dispatch
- *
- * Description:
- *   A new Rx packet was received; dispatch that packet to the network layer
- *   as necessary.
- *
- * Input Parameters:
- *   priv  - Reference to the driver state structure
- *
- * Returned Value:
- *   None
- *
- * Assumptions:
- *   Global interrupts are disabled by interrupt handling logic.
- *
- ****************************************************************************/
-
-static inline void s32k1xx_dispatch(FAR struct s32k1xx_driver_s *priv)
-{
-  #warning Missing logic
-}
 
 /****************************************************************************
  * Function: s32k1xx_receive
@@ -841,7 +760,9 @@ static void s32k1xx_txdone(FAR struct s32k1xx_driver_s *priv, uint32_t flags)
    * canceled.
    */
 
+#ifdef WORK_QUEUE
   wd_cancel(priv->txtimeout);
+#endif
 
   /* FIXME process aborts */
 
@@ -854,7 +775,7 @@ static void s32k1xx_txdone(FAR struct s32k1xx_driver_s *priv, uint32_t flags)
         {
           putreg32(mb_bit, S32K1XX_CAN0_IFLAG1);
           flags &= ~mb_bit;
-#if 0
+#if 0 //FIXME TB ABORT SUPPORT
           const bool txok = priv->tx[mbi].cs.code != CAN_TXMB_ABORT;
           handleTxMailboxInterrupt(mbi, txok, utc_usec);
 #endif
@@ -872,27 +793,6 @@ static void s32k1xx_txdone(FAR struct s32k1xx_driver_s *priv, uint32_t flags)
   devif_poll(&priv->dev, s32k1xx_txpoll);
 }
 
-/****************************************************************************
- * Function: s32k1xx_flexcan_interrupt_work
- *
- * Description:
- *   Perform interrupt related work from the worker thread
- *
- * Input Parameters:
- *   arg - The argument passed when work_queue() was called.
- *
- * Returned Value:
- *   OK on success
- *
- * Assumptions:
- *   The network is locked.
- *
- ****************************************************************************/
-
-static void s32k1xx_flexcan_interrupt_work(FAR void *arg)
-{
-  #warning Missing logic
-}
 
 /****************************************************************************
  * Function: s32k1xx_flexcan_interrupt
@@ -937,53 +837,6 @@ static int s32k1xx_flexcan_interrupt(int irq, FAR void *context, FAR void *arg)
 }
 
 /****************************************************************************
- * Function: s32k1xx_txtimeout_work
- *
- * Description:
- *   Perform TX timeout related work from the worker thread
- *
- * Input Parameters:
- *   arg - The argument passed when work_queue() as called.
- *
- * Returned Value:
- *   OK on success
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static void s32k1xx_txtimeout_work(FAR void *arg)
-{
-  #warning Missing logic
-  ninfo("FLEXCAN: tx timeout work\r\n");
-}
-
-/****************************************************************************
- * Function: s32k1xx_txtimeout_expiry
- *
- * Description:
- *   Our TX watchdog timed out.  Called from the timer interrupt handler.
- *   The last TX never completed.  Reset the hardware and start again.
- *
- * Input Parameters:
- *   argc - The number of available arguments
- *   arg  - The first argument
- *
- * Returned Value:
- *   None
- *
- * Assumptions:
- *   Global interrupts are disabled by the watchdog logic.
- *
- ****************************************************************************/
-
-static void s32k1xx_txtimeout_expiry(int argc, uint32_t arg, ...)
-{
-  #warning Missing logic
-  ninfo("FLEXCAN: tx timeout expiry\r\n");
-}
-
-/****************************************************************************
  * Function: s32k1xx_poll_work
  *
  * Description:
@@ -999,7 +852,7 @@ static void s32k1xx_txtimeout_expiry(int argc, uint32_t arg, ...)
  *   The network is locked.
  *
  ****************************************************************************/
-
+#ifdef WORK_QUEUE
 static void s32k1xx_poll_work(FAR void *arg)
 {
   #warning Missing logic
@@ -1027,6 +880,7 @@ static void s32k1xx_poll_work(FAR void *arg)
            1, (wdparm_t)priv);
   net_unlock();
 }
+#endif
 
 /****************************************************************************
  * Function: s32k1xx_polltimer_expiry
@@ -1046,6 +900,7 @@ static void s32k1xx_poll_work(FAR void *arg)
  *
  ****************************************************************************/
 
+#ifdef WORK_QUEUE
 static void s32k1xx_polltimer_expiry(int argc, uint32_t arg, ...)
 {
   #warning Missing logic
@@ -1053,8 +908,9 @@ static void s32k1xx_polltimer_expiry(int argc, uint32_t arg, ...)
 
   /* Schedule to perform the poll processing on the worker thread. */
 
-  work_queue(ETHWORK, &priv->pollwork, s32k1xx_poll_work, priv, 0);
+  work_queue(CANWORK, &priv->pollwork, s32k1xx_poll_work, priv, 0);
 }
+#endif
 
 static void s32k1xx_setenable(uint32_t enable)
 {
@@ -1140,7 +996,6 @@ static int s32k1xx_ifup(struct net_driver_s *dev)
 {
   FAR struct s32k1xx_driver_s *priv =
     (FAR struct s32k1xx_driver_s *)dev->d_private;
-  uint32_t regval;
 
   #warning Missing logic
 
@@ -1150,10 +1005,12 @@ static int s32k1xx_ifup(struct net_driver_s *dev)
       return -1;
     }
 
-  /* Set and activate a timer process */
+#ifdef WORK_QUEUE
 
+  /* Set and activate a timer process */
   wd_start(priv->txpoll, S32K1XX_WDDELAY, s32k1xx_polltimer_expiry, 1,
            (wdparm_t)priv);
+#endif
 
   priv->bifup = true;
 
@@ -1270,10 +1127,10 @@ static int s32k1xx_txavail(struct net_driver_s *dev)
     {
       /* Schedule to serialize the poll on the worker thread. */
 
-#ifdef WORK_QUEUE_BYPASS
-      s32k1xx_txavail_work(priv);
+#ifdef WORK_QUEUE
+      work_queue(CANWORK, &priv->pollwork, s32k1xx_txavail_work, priv, 0);
 #else
-      work_queue(ETHWORK, &priv->pollwork, s32k1xx_txavail_work, priv, 0);
+      s32k1xx_txavail_work(priv);
 #endif
     }
 
@@ -1413,6 +1270,7 @@ static int s32k1xx_initialize(struct s32k1xx_driver_s *priv)
   for (i = TXMBCOUNT; i < TOTALMBCOUNT; i++)
     {
       priv->rx[i].id.w = 0x0;
+      //FIXME sometimes we get a hard fault here
     }
 
   putreg32(0x0, S32K1XX_CAN0_RXFGMASK);
@@ -1450,27 +1308,6 @@ static int s32k1xx_initialize(struct s32k1xx_driver_s *priv)
 }
 
 /****************************************************************************
- * Function: s32k1xx_initbuffers
- *
- * Description:
- *   Initialize FLEXCAN buffers and descriptors
- *
- * Input Parameters:
- *   priv - Reference to the private FLEXCAN driver state structure
- *
- * Returned Value:
- *   None
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-static void s32k1xx_initbuffers(struct s32k1xx_driver_s *priv)
-{
-  #warning Missing logic
-}
-
-/****************************************************************************
  * Function: s32k1xx_reset
  *
  * Description:
@@ -1621,14 +1458,15 @@ int s32k1xx_netinitialize(int intf)
   priv->dev.d_ifdown  = s32k1xx_ifdown;    /* I/F down callback */
   priv->dev.d_txavail = s32k1xx_txavail;   /* New TX data callback */
 #ifdef CONFIG_NETDEV_IOCTL
-  priv->dev.d_ioctl   = s32k1xx_ioctl;     /* Support PHY ioctl() calls */
+  priv->dev.d_ioctl   = s32k1xx_ioctl;     /* Support CAN ioctl() calls */
 #endif
   priv->dev.d_private = (void *)g_flexcan; /* Used to recover private state from dev */
 
+#ifdef WORK_QUEUE
   /* Create a watchdog for timing polling for and timing of transmissions */
-
   priv->txpoll        = wd_create();       /* Create periodic poll timer */
   priv->txtimeout     = wd_create();       /* Create TX timeout timer */
+#endif
   priv->rx            = (struct mb_s *)(S32K1XX_CAN0_MB);
   priv->tx            = (struct mb_s *)(S32K1XX_CAN0_MB +
                           (sizeof(struct mb_s) * RXMBCOUNT));
diff --git a/include/nuttx/net/net.h b/include/nuttx/net/net.h
index 8c11db7..30808b1 100644
--- a/include/nuttx/net/net.h
+++ b/include/nuttx/net/net.h
@@ -215,6 +215,10 @@ struct sock_intf_s
   CODE ssize_t    (*si_recvfrom)(FAR struct socket *psock, FAR void *buf,
                     size_t len, int flags, FAR struct sockaddr *from,
                     FAR socklen_t *fromlen);
+#ifdef CONFIG_NET_RECVMSG_CMSG
+  CODE ssize_t    (*si_recvmsg)(FAR struct socket *psock,
+		            FAR struct msghdr *msg, int flags);
+#endif
   CODE int        (*si_close)(FAR struct socket *psock);
 #ifdef CONFIG_NET_USRSOCK
   CODE int        (*si_ioctl)(FAR struct socket *psock, int cmd,
@@ -271,6 +275,9 @@ struct socket
 #ifdef CONFIG_NET_SOLINGER
   socktimeo_t   s_linger;    /* Linger timeout value (in deciseconds) */
 #endif
+#ifdef CONFIG_NET_TIMESTAMP
+  int32_t       s_timestamp; /* Socket timestamp enabled/disabled */
+#endif
 #endif
 
   FAR void     *s_conn;      /* Connection inherits from struct socket_conn_s */
diff --git a/libs/libc/net/lib_recvmsg.c b/libs/libc/net/lib_recvmsg.c
index 984a16f..2513dfa 100644
--- a/libs/libc/net/lib_recvmsg.c
+++ b/libs/libc/net/lib_recvmsg.c
@@ -39,7 +39,7 @@
 
 #include <nuttx/config.h>
 
-#ifdef CONFIG_NET
+#if defined(CONFIG_NET) && !defined(CONFIG_NET_RECVMSG_CMSG)
 
 #include <sys/types.h>
 #include <sys/socket.h>
@@ -86,4 +86,4 @@ ssize_t recvmsg(int sockfd, FAR struct msghdr *msg, int flags)
     }
 }
 
-#endif /* CONFIG_NET */
+#endif /* CONFIG_NET && !CONFIG_NET_RECVMSG_CMSG */
diff --git a/net/bluetooth/bluetooth_sockif.c b/net/bluetooth/bluetooth_sockif.c
index 41bcafa..4f4b936 100644
--- a/net/bluetooth/bluetooth_sockif.c
+++ b/net/bluetooth/bluetooth_sockif.c
@@ -109,6 +109,9 @@ const struct sock_intf_s g_bluetooth_sockif =
   NULL,                   /* si_sendfile */
 #endif
   bluetooth_recvfrom,    /* si_recvfrom */
+#ifdef CONFIG_NET_RECVMSG_CMSG
+  NULL,                  /* si_recvmsg */
+#endif
   bluetooth_close        /* si_close */
 };
 
diff --git a/net/can/can.h b/net/can/can.h
index e5d45f0..c74fca4 100644
--- a/net/can/can.h
+++ b/net/can/can.h
@@ -115,6 +115,10 @@ struct can_conn_s
   /* TODO add filter support */
 #endif
   
+#ifdef CONFIG_NET_TIMESTAMP
+  FAR struct socket *psock; /* Needed to get SO_TIMESTAMP value */
+#endif
+
   
 };
 
@@ -254,11 +258,35 @@ uint16_t can_datahandler(FAR struct can_conn_s *conn, FAR uint8_t *buffer,
  *
  ****************************************************************************/
 
+
 ssize_t can_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
                      int flags, FAR struct sockaddr *from,
                      FAR socklen_t *fromlen);
 
 /****************************************************************************
+ * Name: can_recvmsg
+ *
+ * Description:
+ *   recvmsg() receives messages from a socket, and may be used to receive
+ *   data on a socket whether or not it is connection-oriented.
+ *
+ *   If from is not NULL, and the underlying protocol provides the source
+ *   address, this source address is filled in. The argument 'fromlen'
+ *   initialized to the size of the buffer associated with from, and modified
+ *   on return to indicate the actual size of the address stored there.
+ *
+ * Input Parameters:
+ *   psock    A pointer to a NuttX-specific, internal socket structure
+ *   msg      Buffer to receive msg
+ *   flags    Receive flags (ignored)
+ *
+ ****************************************************************************/
+#ifdef CONFIG_NET_RECVMSG_CMSG
+ssize_t can_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg,
+                    size_t len, int flags);
+#endif
+
+/****************************************************************************
  * Name: can_poll
  *
  * Description:
diff --git a/net/can/can_callback.c b/net/can/can_callback.c
index 7b923d3..f8bff86 100644
--- a/net/can/can_callback.c
+++ b/net/can/can_callback.c
@@ -35,6 +35,10 @@
 #include "devif/devif.h"
 #include "can/can.h"
 
+#ifdef CONFIG_NET_TIMESTAMP
+#include <sys/time.h>
+#endif
+
 /****************************************************************************
  * Private Functions
  ****************************************************************************/
@@ -114,6 +118,18 @@ uint16_t can_callback(FAR struct net_driver_s *dev,
 
   if (conn)
     {
+#ifdef CONFIG_NET_TIMESTAMP
+  /* TIMESTAMP sockopt is activated, create timestamp and copy to iob */
+	  if(conn->psock->s_timestamp)
+	    {
+		  struct timespec *ts = (struct timespec*)&dev->d_appdata[dev->d_len];
+		  struct timeval *tv = (struct timeval*)&dev->d_appdata[dev->d_len];
+		  dev->d_len += sizeof(struct timeval);
+		  clock_systimespec(ts);
+		  tv->tv_usec = ts->tv_nsec / 1000;
+	    }
+#endif
+
       /* Perform the callback */
 
       flags = devif_conn_event(dev, conn, flags, conn->list);
diff --git a/net/can/can_recvfrom.c b/net/can/can_recvfrom.c
index 06b133c..98a0b2a 100644
--- a/net/can/can_recvfrom.c
+++ b/net/can/can_recvfrom.c
@@ -46,6 +46,11 @@
 #include "socket/socket.h"
 #include <netpacket/packet.h>
 
+#ifdef CONFIG_NET_TIMESTAMP
+#include <sys/time.h>
+#endif
+
+
 /****************************************************************************
  * Private Types
  ****************************************************************************/
@@ -58,6 +63,10 @@ struct can_recvfrom_s
   size_t       pr_buflen;              /* Length of receive buffer */
   FAR uint8_t *pr_buffer;              /* Pointer to receive buffer */
   ssize_t      pr_recvlen;             /* The received length */
+#ifdef CONFIG_NET_RECVMSG_CMSG
+  size_t       pr_msglen;              /* Length of msg buffer */
+  FAR uint8_t *pr_msgbuf;              /* Pointer to msg buffer */
+#endif
   int          pr_result;              /* Success:OK, failure:negated errno */
 };
 
@@ -294,6 +303,79 @@ static inline int can_readahead(struct can_recvfrom_s *pstate)
   return 0;
 }
 
+/****************************************************************************
+ * Name: can_readahead
+ *
+ * Description:
+ *   Copy the read-ahead data from the packet
+ *
+ * Input Parameters:
+ *   pstate   recvfrom state structure
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *   The network is locked.
+ *
+ ****************************************************************************/
+#ifdef CONFIG_NET_TIMESTAMP
+static inline int can_readahead_timestamp(struct can_conn_s *conn, FAR uint8_t *buffer)
+{
+  FAR struct iob_s *iob;
+  int recvlen;
+
+
+  if ((iob = iob_peek_queue(&conn->readahead)) != NULL)
+    {
+      DEBUGASSERT(iob->io_pktlen > 0);
+
+      /* Transfer that buffered data from the I/O buffer chain into
+       * the user buffer.
+       */
+
+      recvlen = iob_copyout(buffer, iob, sizeof(struct timeval), 0);
+
+      /* If we took all of the data from the I/O buffer chain is empty, then
+       * release it.  If there is still data available in the I/O buffer
+       * chain, then just trim the data that we have taken from the
+       * beginning of the I/O buffer chain.
+       */
+
+      if (recvlen >= iob->io_pktlen)
+        {
+          FAR struct iob_s *tmp;
+
+          /* Remove the I/O buffer chain from the head of the read-ahead
+           * buffer queue.
+           */
+
+          tmp = iob_remove_queue(&conn->readahead);
+          DEBUGASSERT(tmp == iob);
+          UNUSED(tmp);
+
+          /* And free the I/O buffer chain */
+
+          iob_free_chain(iob, IOBUSER_NET_CAN_READAHEAD);
+        }
+      else
+        {
+          /* The bytes that we have received from the head of the I/O
+           * buffer chain (probably changing the head of the I/O
+           * buffer queue).
+           */
+
+          iob_trimhead_queue(&conn->readahead, recvlen,
+                             IOBUSER_NET_CAN_READAHEAD);
+        }
+
+      return recvlen;
+    }
+
+  return 0;
+}
+#endif
+
 #ifdef CONFIG_NET_CANPROTO_OPTIONS
 static int can_recv_filter(struct can_conn_s *conn, canid_t id)
 {
@@ -360,6 +442,22 @@ static uint16_t can_recvfrom_eventhandler(FAR struct net_driver_s *dev,
 
           can_newdata(dev, pstate);
 
+#ifdef CONFIG_NET_TIMESTAMP
+		  if(pstate->pr_sock->s_timestamp)
+			{
+			  if(pstate->pr_msglen == sizeof(struct timeval))
+			    {
+				  can_readahead_timestamp(conn, pstate->pr_msgbuf);
+			    }
+			  else
+			    {
+				/* We still have to consume the data otherwise IOB gets full */
+				  uint8_t dummy_buf[sizeof(struct timeval)];
+				  can_readahead_timestamp(conn, &dummy_buf);
+			    }
+			}
+#endif
+
           /* We are finished. */
 
           /* Don't allow any further call backs. */
@@ -559,4 +657,158 @@ errout_with_state:
   return ret;
 }
 
+/****************************************************************************
+ * Name: can_recvmsg
+ *
+ * Description:
+ *   recvmsg() receives messages from a socket, and may be used to receive
+ *   data on a socket whether or not it is connection-oriented.
+ *
+ *   If from is not NULL, and the underlying protocol provides the source
+ *   address, this source address is filled in. The argument 'fromlen'
+ *   initialized to the size of the buffer associated with from, and modified
+ *   on return to indicate the actual size of the address stored there.
+ *
+ * Input Parameters:
+ *   psock    A pointer to a NuttX-specific, internal socket structure
+ *   msg      Buffer to receive msg
+ *   flags    Receive flags (ignored)
+ *
+ ****************************************************************************/
+#ifdef CONFIG_NET_RECVMSG_CMSG
+ssize_t can_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg,
+                    size_t len, int flags)
+{
+  FAR struct can_conn_s *conn;
+  FAR struct net_driver_s *dev;
+  struct can_recvfrom_s state;
+  int ret;
+
+  DEBUGASSERT(psock != NULL && psock->s_conn != NULL && msg != NULL);
+
+  conn = (FAR struct can_conn_s *)psock->s_conn;
+
+  if (psock->s_type != SOCK_RAW)
+    {
+      nerr("ERROR: Unsupported socket type: %d\n", psock->s_type);
+      ret = -ENOSYS;
+    }
+
+  net_lock();
+
+  /* Initialize the state structure. */
+
+  memset(&state, 0, sizeof(struct can_recvfrom_s));
+
+  /* This semaphore is used for signaling and, hence, should not have
+   * priority inheritance enabled.
+   */
+
+  nxsem_init(&state.pr_sem, 0, 0); /* Doesn't really fail */
+  nxsem_setprotocol(&state.pr_sem, SEM_PRIO_NONE);
+
+
+  state.pr_buflen = msg->msg_iov->iov_len;
+  state.pr_buffer = msg->msg_iov->iov_base;
+#ifdef CONFIG_NET_TIMESTAMP
+  if(psock->s_timestamp && msg->msg_controllen == (sizeof(struct cmsghdr) + sizeof(struct timeval)))
+    {
+	  struct cmsghdr* cmsg = CMSG_FIRSTHDR(msg);
+	  state.pr_msglen = sizeof(struct timeval);
+	  state.pr_msgbuf = CMSG_DATA(cmsg);
+	  cmsg->cmsg_level = SOL_SOCKET;
+	  cmsg->cmsg_type = SO_TIMESTAMP;
+	  cmsg->cmsg_len = state.pr_msglen;
+    }
+#endif
+  state.pr_sock   = psock;
+
+  /* Handle any any CAN data already buffered in a read-ahead buffer.  NOTE
+   * that there may be read-ahead data to be retrieved even after the
+   * socket has been disconnected.
+   */
+
+  ret = can_readahead(&state);
+  if (ret > 0)
+    {
+#ifdef CONFIG_NET_TIMESTAMP
+	  if(psock->s_timestamp)
+	    {
+		  if(state.pr_msglen == sizeof(struct timeval))
+		    {
+			  can_readahead_timestamp(conn, state.pr_msgbuf);
+		    }
+		  else
+		    {
+			/* We still have to consume the data otherwise IOB gets full */
+		    uint8_t dummy_buf[sizeof(struct timeval)];
+			can_readahead_timestamp(conn, &dummy_buf);
+		    }
+	    }
+#endif
+      goto errout_with_state;
+    }
+
+  ret = state.pr_recvlen;
+
+  /* Handle non-blocking CAN sockets */
+
+  if (_SS_ISNONBLOCK(psock->s_flags) || (flags & MSG_DONTWAIT) != 0)
+    {
+      /* Return the number of bytes read from the read-ahead buffer if
+       * something was received (already in 'ret'); EAGAIN if not.
+       */
+
+      if (ret < 0)
+        {
+          /* Nothing was received */
+
+          ret = -EAGAIN;
+          goto errout_with_state;
+        }
+    }
+
+  /* Get the device driver that will service this transfer */
+
+  dev  = conn->dev;
+  if (dev == NULL)
+    {
+      ret = -ENODEV;
+      goto errout_with_state;
+    }
+
+  /* Set up the callback in the connection */
+
+  state.pr_cb = can_callback_alloc(dev, conn);
+  if (state.pr_cb)
+    {
+      state.pr_cb->flags  = (CAN_NEWDATA | CAN_POLL);
+      state.pr_cb->priv   = (FAR void *)&state;
+      state.pr_cb->event  = can_recvfrom_eventhandler;
+
+      /* Wait for either the receive to complete or for an error/timeout to
+       * occur. NOTES:  (1) net_lockedwait will also terminate if a signal
+       * is received, (2) the network is locked!  It will be un-locked while
+       * the task sleeps and automatically re-locked when the task restarts.
+       */
+
+      ret = net_lockedwait(&state.pr_sem);
+
+      /* Make sure that no further events are processed */
+
+      can_callback_free(dev, conn, state.pr_cb);
+      ret = can_recvfrom_result(ret, &state);
+    }
+  else
+    {
+      ret = -EBUSY;
+    }
+
+errout_with_state:
+  net_unlock();
+  nxsem_destroy(&state.pr_sem);
+  return ret;
+}
+#endif
+
 #endif /* CONFIG_NET_CAN */
diff --git a/net/can/can_sockif.c b/net/can/can_sockif.c
index 4deef14..844ac3b 100644
--- a/net/can/can_sockif.c
+++ b/net/can/can_sockif.c
@@ -93,6 +93,9 @@ const struct sock_intf_s g_can_sockif =
   NULL,             /* si_sendfile */
 #endif
   can_recvfrom,     /* si_recvfrom */
+#ifdef CONFIG_NET_RECVMSG_CMSG
+  can_recvmsg,      /* si_recvmsg */
+#endif
   can_close         /* si_close */
 };
 
@@ -105,7 +108,7 @@ const struct sock_intf_s g_can_sockif =
  *
  * Description:
  *   This function is called to perform the actual CAN receive operation
- *   via the device interface layer.
+ *   via the device interface layer. from can_input()
  *
  * Input Parameters:
  *   dev      The structure of the network driver that caused the event
@@ -229,6 +232,11 @@ static int can_setup(FAR struct socket *psock, int protocol)
           return -ENOMEM;
         }
 
+#ifdef CONFIG_NET_TIMESTAMP
+      /* Store psock in conn se we can read the SO_TIMESTAMP value */
+      conn->psock = psock;
+#endif
+
       /* Initialize the connection instance */
 
       conn->protocol = (uint8_t)protocol;
diff --git a/net/icmp/icmp_sockif.c b/net/icmp/icmp_sockif.c
index 983eb71..c81592e 100644
--- a/net/icmp/icmp_sockif.c
+++ b/net/icmp/icmp_sockif.c
@@ -102,6 +102,9 @@ const struct sock_intf_s g_icmp_sockif =
   NULL,             /* si_sendfile */
 #endif
   icmp_recvfrom,    /* si_recvfrom */
+#ifdef CONFIG_NET_RECVMSG_CMSG
+  NULL,             /* si_recvmsg */
+#endif
   icmp_close        /* si_close */
 };
 
diff --git a/net/icmpv6/icmpv6_sockif.c b/net/icmpv6/icmpv6_sockif.c
index c99d184..29e5e47 100644
--- a/net/icmpv6/icmpv6_sockif.c
+++ b/net/icmpv6/icmpv6_sockif.c
@@ -102,6 +102,9 @@ const struct sock_intf_s g_icmpv6_sockif =
   NULL,               /* si_sendfile */
 #endif
   icmpv6_recvfrom,    /* si_recvfrom */
+#ifdef CONFIG_NET_RECVMSG_CMSG
+  NULL,               /* si_recvmsg */
+#endif
   icmpv6_close        /* si_close */
 };
 
diff --git a/net/ieee802154/ieee802154_sockif.c b/net/ieee802154/ieee802154_sockif.c
index 216264a..d1ac29b 100644
--- a/net/ieee802154/ieee802154_sockif.c
+++ b/net/ieee802154/ieee802154_sockif.c
@@ -107,6 +107,9 @@ const struct sock_intf_s g_ieee802154_sockif =
   NULL,                   /* si_sendfile */
 #endif
   ieee802154_recvfrom,    /* si_recvfrom */
+#ifdef CONFIG_NET_RECVMSG_CMSG
+  NULL,                   /* si_recvmsg */
+#endif
   ieee802154_close        /* si_close */
 };
 
diff --git a/net/inet/inet_sockif.c b/net/inet/inet_sockif.c
index 9456510..2a09c45 100644
--- a/net/inet/inet_sockif.c
+++ b/net/inet/inet_sockif.c
@@ -117,6 +117,9 @@ static const struct sock_intf_s g_inet_sockif =
   inet_sendfile,    /* si_sendfile */
 #endif
   inet_recvfrom,    /* si_recvfrom */
+#ifdef CONFIG_NET_RECVMSG_CMSG
+  NULL,             /* si_recvmsg */
+#endif
   inet_close        /* si_close */
 };
 
diff --git a/net/local/local_sockif.c b/net/local/local_sockif.c
index f2bbcb1..62d56b5 100644
--- a/net/local/local_sockif.c
+++ b/net/local/local_sockif.c
@@ -110,6 +110,9 @@ const struct sock_intf_s g_local_sockif =
   NULL,              /* si_sendfile */
 #endif
   local_recvfrom,    /* si_recvfrom */
+#ifdef CONFIG_NET_RECVMSG_CMSG
+  NULL,              /* si_recvmsg */
+#endif
   local_close        /* si_close */
 };
 
diff --git a/net/netlink/netlink_sockif.c b/net/netlink/netlink_sockif.c
index 577d520..970aed4 100644
--- a/net/netlink/netlink_sockif.c
+++ b/net/netlink/netlink_sockif.c
@@ -111,6 +111,9 @@ const struct sock_intf_s g_netlink_sockif =
   NULL,                 /* si_sendfile */
 #endif
   netlink_recvfrom,     /* si_recvfrom */
+#ifdef CONFIG_NET_RECVMSG_CMSG
+  NULL,                 /* si_recvmsg */
+#endif
   netlink_close         /* si_close */
 };
 
diff --git a/net/pkt/pkt_sockif.c b/net/pkt/pkt_sockif.c
index e189ddc..bbabf42 100644
--- a/net/pkt/pkt_sockif.c
+++ b/net/pkt/pkt_sockif.c
@@ -108,6 +108,9 @@ const struct sock_intf_s g_pkt_sockif =
   NULL,            /* si_sendfile */
 #endif
   pkt_recvfrom,    /* si_recvfrom */
+#ifdef CONFIG_NET_RECVMSG_CMSG
+  NULL,            /* si_recvmsg */
+#endif
   pkt_close        /* si_close */
 };
 
diff --git a/net/socket/Kconfig b/net/socket/Kconfig
index 8b71ade..f4c9408 100644
--- a/net/socket/Kconfig
+++ b/net/socket/Kconfig
@@ -55,5 +55,21 @@ config NET_SOLINGER
 		Enable or disable support for the SO_LINGER socket option.  Requires
 		write buffer support.
 
+config NET_TIMESTAMP
+	bool "SO_TIMESTAMP socket option"
+	default n
+	depends on NET_CAN && NET_RECVMSG_CMSG
+	---help---
+		Enable or disable support for the SO_TIMESTAMP socket option. Currently only tested & implemented in SocketCAN but should work on all sockets
+
 endif # NET_SOCKOPTS
+
+config NET_RECVMSG_CMSG
+	bool "recvmsg() control messages (CMSG) support"
+	default n
+	---help---
+		Enable or disable support for control messages in the recvmsg function.
+		Control messages (also defined in POSIX 1003.1g as ancillary data object information).
+		Includes additional information on the packet received.
+
 endmenu # Socket Support
diff --git a/net/socket/Make.defs b/net/socket/Make.defs
index 47fb4d2..2be9dbf 100644
--- a/net/socket/Make.defs
+++ b/net/socket/Make.defs
@@ -74,3 +74,8 @@ endif
 
 DEPPATH += --dep-path socket
 VPATH += :socket
+
+# Support for recvmsg() with control messages (CMSG)
+ifeq ($(CONFIG_NET_RECVMSG_CMSG),y)
+SOCK_CSRCS += recvmsg.c
+endif
diff --git a/net/socket/getsockopt.c b/net/socket/getsockopt.c
index fa58e6d..581edc0 100644
--- a/net/socket/getsockopt.c
+++ b/net/socket/getsockopt.c
@@ -278,6 +278,19 @@ static int psock_socketlevel_option(FAR struct socket *psock, int option,
         }
         break;
 
+#ifdef CONFIG_NET_TIMESTAMP
+      case SO_TIMESTAMP:
+        {
+          if (*value_len != sizeof(int))
+            {
+              return -EINVAL;
+            }
+
+          *(FAR int *)value = (int)psock->s_timestamp;
+        }
+        break;
+#endif
+
       /* The following are not yet implemented
        * (return values other than {0,1})
        */
diff --git a/net/socket/setsockopt.c b/net/socket/setsockopt.c
index 46e1b6e..fddf0c1 100644
--- a/net/socket/setsockopt.c
+++ b/net/socket/setsockopt.c
@@ -279,6 +279,30 @@ static int psock_socketlevel_option(FAR struct socket *psock, int option,
         }
         break;
 #endif
+
+#ifdef CONFIG_NET_TIMESTAMP
+      case SO_TIMESTAMP:  /* Generates a timestamp for each incoming packet */
+        {
+
+          /* Verify that option is at least the size of an integer. */
+
+          if (value_len < sizeof(FAR int32_t))
+            {
+              return -EINVAL;
+            }
+
+          /* Lock the network so that we have exclusive access to the socket
+           * options.
+           */
+
+          net_lock();
+
+          psock->s_timestamp = *((FAR int32_t*)value);
+
+          net_unlock();
+        }
+        break;
+#endif
       /* The following are not yet implemented */
 
       case SO_RCVBUF:     /* Sets receive buffer size */
diff --git a/net/socket/socket.h b/net/socket/socket.h
index 0f809ac..80279da 100644
--- a/net/socket/socket.h
+++ b/net/socket/socket.h
@@ -80,7 +80,7 @@
 
 /* This is the largest option value.  REVISIT: belongs in sys/socket.h */
 
-#define _SO_MAXOPT       (15)
+#define _SO_MAXOPT       (29)
 
 /* Macros to set, test, clear options */
 


[incubator-nuttx] 04/31: PoC S32K1XX FlexCAN sends CAN msgs through SocketCAN

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch SocketCAN
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit ff4116d515ca00795a59119cc062f8c3b06d692e
Author: Peter van der Perk <pe...@nxp.com>
AuthorDate: Wed Feb 19 11:24:31 2020 +0100

    PoC S32K1XX FlexCAN sends CAN msgs through SocketCAN
---
 arch/arm/src/s32k1xx/Kconfig                       |    4 +
 arch/arm/src/s32k1xx/Make.defs                     |    4 +
 arch/arm/src/s32k1xx/hardware/s32k1xx_flexcan.h    |   57 +-
 arch/arm/src/s32k1xx/s32k1xx_flexcan.c             | 1422 ++++++++++++++++++++
 .../arm/src/s32k1xx/s32k1xx_flexcan.h              |  120 +-
 include/nuttx/can.h                                |  279 ++++
 include/nuttx/net/can.h                            |   88 ++
 include/nuttx/net/net.h                            |    3 +-
 net/can/Make.defs                                  |    6 +
 net/can/can.h                                      |   75 ++
 net/{devif/devif_pktsend.c => can/can_callback.c}  |   70 +-
 net/can/can_poll.c                                 |  107 ++
 net/can/can_send.c                                 |  264 ++++
 net/can/can_sockif.c                               |   81 +-
 net/devif/Make.defs                                |    2 +-
 net/devif/devif.h                                  |    4 +-
 net/devif/devif_pktsend.c                          |    2 +-
 net/devif/devif_poll.c                             |   49 +
 net/local/local_sendpacket.c                       |    1 +
 net/netdev/netdev_register.c                       |   12 +
 20 files changed, 2487 insertions(+), 163 deletions(-)

diff --git a/arch/arm/src/s32k1xx/Kconfig b/arch/arm/src/s32k1xx/Kconfig
index 63e0cd9..68f9bb6 100644
--- a/arch/arm/src/s32k1xx/Kconfig
+++ b/arch/arm/src/s32k1xx/Kconfig
@@ -150,6 +150,10 @@ config S32K1XX_ENET
 	default n
 	depends on S32K1XX_HAVE_ENET
 
+config S32K1XX_FLEXCAN
+	bool "FLEXCAN"
+	default n
+
 menuconfig S32K1XX_LPI2C0
 	bool "LPI2C0"
 	default n
diff --git a/arch/arm/src/s32k1xx/Make.defs b/arch/arm/src/s32k1xx/Make.defs
index a06fa86..940dc05 100644
--- a/arch/arm/src/s32k1xx/Make.defs
+++ b/arch/arm/src/s32k1xx/Make.defs
@@ -87,6 +87,10 @@ ifeq ($(CONFIG_S32K1XX_ENET),y)
 CHIP_CSRCS += s32k1xx_enet.c
 endif
 
+ifeq ($(CONFIG_S32K1XX_FLEXCAN),y)
+CHIP_CSRCS += s32k1xx_flexcan.c
+endif
+
 ifeq ($(CONFIG_S32K1XX_RTC),y)
 CHIP_CSRCS += s32k1xx_rtc.c
 endif
diff --git a/arch/arm/src/s32k1xx/hardware/s32k1xx_flexcan.h b/arch/arm/src/s32k1xx/hardware/s32k1xx_flexcan.h
index fa9c36f..03d3d90 100644
--- a/arch/arm/src/s32k1xx/hardware/s32k1xx_flexcan.h
+++ b/arch/arm/src/s32k1xx/hardware/s32k1xx_flexcan.h
@@ -66,6 +66,9 @@
 #define S32K1XX_CAN_CRCR_OFFSET       0x0044  /* CRC Register */
 #define S32K1XX_CAN_RXFGMASK_OFFSET   0x0048  /* Rx FIFO Global Mask Register */
 #define S32K1XX_CAN_RXFIR_OFFSET      0x004c  /* Rx FIFO Information Register */
+#define S32K1XX_CAN_CBT_OFFSET        0x0050  /* CAN Bit Timing register */
+
+#define S32K1XX_CAN_MB_OFFSET         0x0080  /* CAN MB register */
 
 #define S32K1XX_CAN_RXIMR_OFFSET(n)   (0x0880 + ((n) << 2)) /* Rn Individual Mask Registers */
 #  define S32K1XX_CAN_RXIMR0_OFFSET   0x0880  /* R0 Individual Mask Registers */
@@ -162,6 +165,11 @@
 #define S32K1XX_CAN0_CRCR             (S32K1XX_FLEXCAN0_BASE + S32K1XX_CAN_CRCR_OFFSET)
 #define S32K1XX_CAN0_RXFGMASK         (S32K1XX_FLEXCAN0_BASE + S32K1XX_CAN_RXFGMASK_OFFSET)
 #define S32K1XX_CAN0_RXFIR            (S32K1XX_FLEXCAN0_BASE + S32K1XX_CAN_RXFIR_OFFSET)
+#define S32K1XX_CAN0_CBT              (S32K1XX_FLEXCAN0_BASE + S32K1XX_CAN_CBT_OFFSET)
+#define S32K1XX_CAN0_MB               (S32K1XX_FLEXCAN0_BASE + S32K1XX_CAN_MB_OFFSET)
+#define S32K1XX_CAN0_FDCTRL           (S32K1XX_FLEXCAN0_BASE + S32K1XX_CAN_FDCTRL_OFFSET)
+#define S32K1XX_CAN0_FDCBT            (S32K1XX_FLEXCAN0_BASE + S32K1XX_CAN_FDCBT_OFFSET)
+#define S32K1XX_CAN0_FDCRC            (S32K1XX_FLEXCAN0_BASE + S32K1XX_CAN_FDCRC_OFFSET)
 
 #define S32K1XX_CAN0_RXIMR(n)         (S32K1XX_FLEXCAN0_BASE + S32K1XX_CAN_RXIMR_OFFSET(n))
 #  define S32K1XX_CAN0_RXIMR0         (S32K1XX_FLEXCAN0_BASE + S32K1XX_CAN_RXIMR0_OFFSET)
@@ -340,7 +348,8 @@
 #  define CAN_MCR_IDAM_FMTB           (1 << CAN_MCR_IDAM_SHIFT) /* Format B: Two full (or partial) IDs */
 #  define CAN_MCR_IDAM_FMTC           (2 << CAN_MCR_IDAM_SHIFT) /* Format C: Four partial IDs */
 #  define CAN_MCR_IDAM_FMTD           (3 << CAN_MCR_IDAM_SHIFT) /* Format D: All frames rejected */
-                                                /* Bits 10-11: Reserved */
+                                                /* Bit 10: Reserved */
+#define CAN_MCR_FDEN                  (1 << 11) /* Bit 11: CAN FD operation enable */
 #define CAN_MCR_AEN                   (1 << 12) /* Bit 12: Abort Enable */
 #define CAN_MCR_LPRIOEN               (1 << 13) /* Bit 13: Local Priority Enable */
                                                 /* Bits 14-15: Reserved */
@@ -454,7 +463,12 @@
 #define CAN_IFLAG1(n)                 (1 << (n)) /* Bit n: Buffer MBn Interrupt, n=0..4,8..31 */
 
 /* Control 2 Register */
-                                                /* Bits 0-15: Reserved */
+                                                /* Bits 0-10: Reserved */
+#define CAN_CTRL2_EDFLTDIS            (1 << 11) /* Bit 11:  Edge Filter Disable */
+#define CAN_CTRL2_ISOCANFDEN          (1 << 12) /* Bit 12:  ISO CAN FD Enable */
+                                                /* Bit 13:  Reserved */
+#define CAN_CTRL2_PREXCEN             (1 << 14) /* Bit 14:  Protocol Exception Enable */
+#define CAN_CTRL2_TIMER_SRC           (1 << 15) /* Bit 15:  Timer Source */
 #define CAN_CTRL2_EACEN               (1 << 16) /* Bit 16:  Entire Frame Arbitration Field Comparison Enable (Rx) */
 #define CAN_CTRL2_RRS                 (1 << 17) /* Bit 17:  Remote Request Storing */
 #define CAN_CTRL2_MRP                 (1 << 18) /* Bit 18:  Mailboxes Reception Priority */
@@ -506,6 +520,45 @@
 #define CAN_RXFIR_IDHIT_SHIFT         (0)       /* Bits 0-8: Identifier Acceptance Filter Hit Indicator */
 #define CAN_RXFIR_IDHIT_MASK          (0x1ff << CAN_RXFIR_IDHIT_SHIFT)
 
+/* CAN Bit Timing register (CBT) */
+
+/* CBT Bit Fields */
+#define CAN_CBT_EPSEG2(x)             (((uint32_t)(((uint32_t)(x)) << 0))  & 0x1F)
+#define CAN_CBT_EPSEG1(x)             (((uint32_t)(((uint32_t)(x)) << 5))  & 0x3E0)
+#define CAN_CBT_EPROPSEG(x)           (((uint32_t)(((uint32_t)(x)) << 10)) & 0xFC00)
+#define CAN_CBT_ERJW(x)               (((uint32_t)(((uint32_t)(x)) << 16)) & 0x1F0000)
+#define CAN_CBT_EPRESDIV(x)           (((uint32_t)(((uint32_t)(x)) << 21)) & 0x7FE00000)
+#define CAN_CBT_BTF                   (1 << 31) /* Bit 31: Bit Timing Format Enable */
+
+/* CAN MB TX codes */
+#define CAN_TXMB_INACTIVE             0x8       /* MB is not active.*/
+#define CAN_TXMB_ABORT                0x9       /* MB is aborted.*/
+#define CAN_TXMB_DATAORREMOTE         0xC       /* MB is a TX Data Frame(when MB RTR = 0) or */
+                                                /* MB is a TX Remote Request Frame (when MB RTR = 1).*/
+#define CAN_TXMB_TANSWER              0xE       /* MB is a TX Response Request Frame from */
+                                                /* an incoming Remote Request Frame.*/
+#define CAN_TXMB_NOTUSED              0xF       /* Not used.*/
+
+/* CAN FD Control register (FDCTRL) */
+#define CAN_FDCTRL_TDCVAL(x)          (((uint32_t)(((uint32_t)(x)) << 0))  & 0x3F)
+#define CAN_FDCTRL_TDCOFF(x)          (((uint32_t)(((uint32_t)(x)) << 8))  & 0x1F00)
+#define CAN_FDCTRL_TDCEN              (1 << 14) /* Bit 14: TDC fail */
+#define CAN_FDCTRL_TDCEN              (1 << 15) /* Bit 15: TDC enable */
+#define CAN_FDCTRL_MBDSR0(x)          (((uint32_t)(((uint32_t)(x)) << 16)) & 0x30000)
+#define CAN_FDCTRL_FDRATE             (1 << 31) /* Bit 31: FD rate */
+
+/* FDCBT Bit Fields */
+#define CAN_FDCBT_FPSEG2(x)           (((uint32_t)(((uint32_t)(x)) << 0))  & 0x7)
+#define CAN_FDCBT_FPSEG1(x)           (((uint32_t)(((uint32_t)(x)) << 5))  & 0xE0)
+#define CAN_FDCBT_FPROPSEG(x)         (((uint32_t)(((uint32_t)(x)) << 10)) & 0x7C00)
+#define CAN_FDCBT_FRJW(x)             (((uint32_t)(((uint32_t)(x)) << 16)) & 0x70000)
+#define CAN_FDCBT_FPRESDIV(x)         (((uint32_t)(((uint32_t)(x)) << 20)) & 0x3FF00000)
+
+/* FDCRC Bit Fields */
+#define CAN_FDCRC_FD_TXCRC(x)         (((uint32_t)(((uint32_t)(x)) << 0))  & 0x1FFFFF)
+#define CAN_FDCRC_FD_MBCRC(x)         (((uint32_t)(((uint32_t)(x)) << 24)) & 0x7F000000)
+
+
 /* Rn Individual Mask Registers */
 
 #define CAN_RXIMR(n)                  (1 << (n)) /* Bit n: Individual Mask Bits */
diff --git a/arch/arm/src/s32k1xx/s32k1xx_flexcan.c b/arch/arm/src/s32k1xx/s32k1xx_flexcan.c
new file mode 100644
index 0000000..74a21b8
--- /dev/null
+++ b/arch/arm/src/s32k1xx/s32k1xx_flexcan.c
@@ -0,0 +1,1422 @@
+/****************************************************************************
+ * arch/arm/src/s32k1xx/s32k1xx_flexcan.c
+ *
+ *   Copyright (C) 2019 Gregory Nutt. All rights reserved.
+ *   Authors: Gregory Nutt <gn...@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <time.h>
+#include <string.h>
+#include <debug.h>
+#include <errno.h>
+
+#include <arpa/inet.h>
+
+#include <nuttx/can.h>
+#include <nuttx/wdog.h>
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <nuttx/wqueue.h>
+#include <nuttx/signal.h>
+#include <nuttx/net/mii.h>
+#include <nuttx/net/arp.h>
+#include <nuttx/net/phy.h>
+#include <nuttx/net/netdev.h>
+
+#ifdef CONFIG_NET_PKT
+#  include <nuttx/net/pkt.h>
+#endif
+
+#include "up_arch.h"
+#include "chip.h"
+#include "s32k1xx_config.h"
+#include "hardware/s32k1xx_flexcan.h"
+#include "hardware/s32k1xx_pinmux.h"
+#include "s32k1xx_periphclocks.h"
+#include "s32k1xx_pin.h"
+#include "s32k1xx_flexcan.h"
+
+#ifdef CONFIG_S32K1XX_FLEXCAN
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* If processing is not done at the interrupt level, then work queue support
+ * is required.
+ */
+
+#if !defined(CONFIG_SCHED_WORKQUEUE)
+#  error Work queue support is required
+#else
+
+  /* Select work queue.  Always use the LP work queue if available.  If not,
+   * then LPWORK will re-direct to the HP work queue.
+   *
+   * NOTE:  However, the network should NEVER run on the high priority work
+   * queue!  That queue is intended only to service short back end interrupt
+   * processing that never suspends.  Suspending the high priority work queue
+   * may bring the system to its knees!
+   */
+
+#  define ETHWORK LPWORK
+#endif
+
+/* CONFIG_S32K1XX_FLEXCAN_NETHIFS determines the number of physical interfaces
+ * that will be supported.
+ */
+/*
+#if CONFIG_S32K1XX_FLEXCAN_NETHIFS != 1
+#  error "CONFIG_S32K1XX_FLEXCAN_NETHIFS must be one for now"
+#endif
+
+#if CONFIG_S32K1XX_FLEXCAN_NTXBUFFERS < 1
+#  error "Need at least one TX buffer"
+#endif
+
+#if CONFIG_S32K1XX_FLEXCAN_NRXBUFFERS < 1
+#  error "Need at least one RX buffer"
+#endif*/
+
+#define S32K1XX_FLEXCAN_FIRST_TX_MB 10
+
+#define MaskStdID                   0x000007FF;
+#define MaskExtID                   0x1FFFFFFF;
+
+//Fixme nice variables/constants
+#define NumMBinFiFoAndFilters       10 //FIXME
+#define NumTxMesgBuffers            6
+#define HWMaxMB                     16
+#define TXMBMask                    (0b111111 << NumMBinFiFoAndFilters)
+
+#define CAN_FIFO_NE                 (1 << 5)
+#define CAN_FIFO_OV                 (1 << 6)
+#define CAN_FIFO_WARN               (1 << 7)
+
+static int peak_tx_mailbox_index_ = 0;
+
+
+
+
+/* Normally you would clean the cache after writing new values to the DMA
+ * memory so assure that the dirty cache lines are flushed to memory
+ * before the DMA occurs.  And you would invalid the cache after a data is
+ * received via DMA so that you fetch the actual content of the data from
+ * the cache.
+ *
+ * These conditions are not fully supported here.  If the write-throuch
+ * D-Cache is enabled, however, then many of these issues go away:  The
+ * cache clean operation does nothing (because there are not dirty cache
+ * lines) and the cache invalid operation is innocuous (because there are
+ * never dirty cache lines to be lost; valid data will always be reloaded).
+ *
+ * At present, we simply insist that write through cache be enabled.
+ */
+
+#if defined(CONFIG_ARMV7M_DCACHE) && !defined(CONFIG_ARMV7M_DCACHE_WRITETHROUGH)
+#  error Write back D-Cache not yet supported
+#endif
+
+/* TX poll delay = 1 seconds. CLK_TCK is the number of clock ticks per
+ * second.
+ */
+
+#define S32K1XX_WDDELAY     (1*CLK_TCK)
+
+/* Align assuming that the D-Cache is enabled (probably 32-bytes).
+ *
+ * REVISIT: The size of descriptors and buffers must also be in even units
+ * of the cache line size  That is because the operations to clean and
+ * invalidate the cache will operate on a full 32-byte cache line.  If
+ * CONFIG_FLEXCAN_ENHANCEDBD is selected, then the size of the descriptor is
+ * 32-bytes (and probably already the correct size for the cache line);
+ * otherwise, the size of the descriptors much smaller, only 8 bytes.
+ */
+
+#define FLEXCAN_ALIGN        ARMV7M_DCACHE_LINESIZE
+#define FLEXCAN_ALIGN_MASK   (FLEXCAN_ALIGN - 1)
+#define FLEXCAN_ALIGN_UP(n)  (((n) + FLEXCAN_ALIGN_MASK) & ~FLEXCAN_ALIGN_MASK)
+
+/* TX timeout = 1 minute */
+
+#define S32K1XX_TXTIMEOUT   (60*CLK_TCK)
+#define MII_MAXPOLLS      (0x1ffff)
+#define LINK_WAITUS       (500*1000)
+#define LINK_NLOOPS       (10)
+
+/* Interrupt groups */
+
+#define RX_INTERRUPTS     (FLEXCAN_INT_RXF | FLEXCAN_INT_RXB)
+#define TX_INTERRUPTS      FLEXCAN_INT_TXF
+#define ERROR_INTERRUPTS  (FLEXCAN_INT_UN    | FLEXCAN_INT_RL   | FLEXCAN_INT_LC | \
+                           FLEXCAN_INT_EBERR | FLEXCAN_INT_BABT | FLEXCAN_INT_BABR)
+
+/* The subset of errors that require us to reset the hardware - this list
+ * may need to be revisited if it's found that some error above leads to a
+ * locking up of the Ethernet interface.
+ */
+
+#define CRITICAL_ERROR    (FLEXCAN_INT_UN | FLEXCAN_INT_RL | FLEXCAN_INT_EBERR )
+
+/* This is a helper pointer for accessing the contents of the Ethernet header */
+
+#define BUF ((struct eth_hdr_s *)priv->dev.d_buf)
+
+#define S32K1XX_BUF_SIZE  FLEXCAN_ALIGN_UP(CONFIG_NET_ETH_PKTSIZE)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+
+union TXcsType
+{
+	volatile uint32_t w;
+	struct
+	{
+		volatile uint32_t time_stamp : 16;
+		volatile uint32_t dlc : 4;
+		volatile uint32_t rtr : 1;
+		volatile uint32_t ide : 1;
+		volatile uint32_t srr : 1;
+		volatile uint32_t res : 1;
+		volatile uint32_t code : 4;
+		volatile uint32_t res2 : 4;
+	};
+};
+
+union RXcsType
+{
+	volatile uint32_t cs;
+	struct
+	{
+		volatile uint32_t time_stamp : 16;
+		volatile uint32_t dlc : 4;
+		volatile uint32_t rtr : 1;
+		volatile uint32_t ide : 1;
+		volatile uint32_t srr : 1;
+		volatile uint32_t res : 9;
+	};
+};
+
+union IDType
+{
+	volatile uint32_t w;
+	struct
+	{
+		volatile uint32_t ext : 29;
+		volatile uint32_t resex : 3;
+	};
+	struct
+	{
+		volatile uint32_t res : 18;
+		volatile uint32_t std : 11;
+		volatile uint32_t resstd : 3;
+	};
+};
+
+union DataType
+{
+	volatile uint32_t l;
+	volatile uint32_t h;
+	struct
+	{
+		volatile uint32_t b3 : 8;
+		volatile uint32_t b2 : 8;
+		volatile uint32_t b1 : 8;
+		volatile uint32_t b0 : 8;
+		volatile uint32_t b7 : 8;
+		volatile uint32_t b6 : 8;
+		volatile uint32_t b5 : 8;
+		volatile uint32_t b4 : 8;
+	};
+};
+
+struct MbTx
+{
+	union TXcsType CS;
+	union IDType ID;
+	union DataType data;
+};
+
+struct MbRx
+{
+	union RXcsType CS;
+	union IDType ID;
+	union DataType data;
+};
+
+/* The s32k1xx_driver_s encapsulates all state information for a single
+ * hardware interface
+ */
+
+struct s32k1xx_driver_s
+{
+  bool bifup;                  /* true:ifup false:ifdown */
+  uint8_t txtail;              /* The oldest busy TX descriptor */
+  uint8_t txhead;              /* The next TX descriptor to use */
+  uint8_t rxtail;              /* The next RX descriptor to use */
+  uint8_t phyaddr;             /* Selected PHY address */
+  WDOG_ID txpoll;              /* TX poll timer */
+  WDOG_ID txtimeout;           /* TX timeout timer */
+  struct work_s irqwork;       /* For deferring interrupt work to the work queue */
+  struct work_s pollwork;      /* For deferring poll work to the work queue */
+  struct enet_desc_s *txdesc;  /* A pointer to the list of TX descriptor */
+  struct enet_desc_s *rxdesc;  /* A pointer to the list of RX descriptors */
+
+  /* This holds the information visible to the NuttX network */
+
+  struct net_driver_s dev;     /* Interface understood by the network */
+
+  struct MbRx *rx;
+  struct MbTx *tx;
+
+};
+
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct s32k1xx_driver_s g_flexcan[CONFIG_S32K1XX_ENET_NETHIFS];
+
+static uint8_t g_desc_pool[2000]
+               __attribute__((aligned(ARMV7M_DCACHE_LINESIZE)));
+
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Utility functions */
+
+#ifndef S32K1XX_BUFFERS_SWAP
+#  define s32k1xx_swap32(value) (value)
+#  define s32k1xx_swap16(value) (value)
+#else
+#if 0 /* Use builtins if the compiler supports them */
+static inline uint32_t s32k1xx_swap32(uint32_t value);
+static inline uint16_t s32k1xx_swap16(uint16_t value);
+#else
+#  define s32k1xx_swap32 __builtin_bswap32
+#  define s32k1xx_swap16 __builtin_bswap16
+#endif
+#endif
+
+/* Common TX logic */
+
+static bool s32k1xx_txringfull(FAR struct s32k1xx_driver_s *priv);
+static int  s32k1xx_transmit(FAR struct s32k1xx_driver_s *priv);
+static int  s32k1xx_txpoll(struct net_driver_s *dev);
+
+/* Interrupt handling */
+
+static void s32k1xx_dispatch(FAR struct s32k1xx_driver_s *priv);
+static void s32k1xx_receive(FAR struct s32k1xx_driver_s *priv);
+static void s32k1xx_txdone(FAR struct s32k1xx_driver_s *priv);
+
+static void s32k1xx_flexcan_interrupt_work(FAR void *arg);
+static int  s32k1xx_flexcan_interrupt(int irq, FAR void *context,
+                                   FAR void *arg);
+
+/* Watchdog timer expirations */
+
+static void s32k1xx_txtimeout_work(FAR void *arg);
+static void s32k1xx_txtimeout_expiry(int argc, uint32_t arg, ...);
+
+static void s32k1xx_poll_work(FAR void *arg);
+static void s32k1xx_polltimer_expiry(int argc, uint32_t arg, ...);
+
+/* NuttX callback functions */
+
+static int  s32k1xx_ifup(struct net_driver_s *dev);
+static int  s32k1xx_ifdown(struct net_driver_s *dev);
+
+static void s32k1xx_txavail_work(FAR void *arg);
+static int  s32k1xx_txavail(struct net_driver_s *dev);
+
+#ifdef CONFIG_NET_MCASTGROUP
+static int  s32k1xx_addmac(struct net_driver_s *dev,
+              FAR const uint8_t *mac);
+static int  s32k1xx_rmmac(struct net_driver_s *dev, FAR const uint8_t *mac);
+#endif
+
+#ifdef CONFIG_NETDEV_IOCTL
+static int  s32k1xx_ioctl(struct net_driver_s *dev, int cmd,
+            unsigned long arg);
+#endif
+
+/* Initialization */
+
+static void s32k1xx_initbuffers(struct s32k1xx_driver_s *priv);
+static void s32k1xx_reset(struct s32k1xx_driver_s *priv);
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+
+/****************************************************************************
+ * Function: s32k1xx_txringfull
+ *
+ * Description:
+ *   Check if all of the TX descriptors are in use.
+ *
+ * Input Parameters:
+ *   priv  - Reference to the driver state structure
+ *
+ * Returned Value:
+ *   true is the TX ring is full; false if there are free slots at the
+ *   head index.
+ *
+ ****************************************************************************/
+
+static bool s32k1xx_txringfull(FAR struct s32k1xx_driver_s *priv)
+{
+  uint8_t txnext;
+
+  /* Check if there is room in the hardware to hold another outgoing
+   * packet.  The ring is full if incrementing the head pointer would
+   * collide with the tail pointer.
+   */
+
+  txnext = priv->txhead + 1;
+  
+  return priv->txtail == txnext;
+}
+
+/****************************************************************************
+ * Function: s32k1xx_transmit
+ *
+ * Description:
+ *   Start hardware transmission.  Called either from the txdone interrupt
+ *   handling or from watchdog based polling.
+ *
+ * Input Parameters:
+ *   priv  - Reference to the driver state structure
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ * Assumptions:
+ *   May or may not be called from an interrupt handler.  In either case,
+ *   global interrupts are disabled, either explicitly or indirectly through
+ *   interrupt handling logic.
+ *
+ ****************************************************************************/
+
+
+static int s32k1xx_transmit(FAR struct s32k1xx_driver_s *priv)
+{
+  #warning Missing logic
+
+  struct can_frame *frame = (struct can_frame*)priv->dev.d_buf;
+
+  /*printf("CAN id: %i dlc: %i", frame->can_id, frame->can_dlc);
+
+  for(int i = 0; i < frame->can_dlc; i++){
+	  printf(" %02X", frame->data[i]);
+  }
+  printf("\r\n");*/
+
+  /* Attempt to write frame */
+  uint32_t mbi = 0;
+  if ((getreg32(S32K1XX_CAN0_ESR2) & (CAN_ESR2_IMB | CAN_ESR2_VPS)) == (CAN_ESR2_IMB | CAN_ESR2_VPS))
+  {
+	  mbi = (getreg32(S32K1XX_CAN0_ESR2) & CAN_ESR2_LPTM_MASK) >> CAN_ESR2_LPTM_SHIFT;
+  }
+
+  uint32_t mb_bit = 1 << (NumMBinFiFoAndFilters + mbi);
+
+  while (mbi < NumTxMesgBuffers)
+  {
+
+	  if (priv->tx[mbi].CS.code != CAN_TXMB_DATAORREMOTE)
+	  {
+		  putreg32(mb_bit, S32K1XX_CAN0_IFLAG1);
+		  break;
+	  }
+	  mb_bit <<= 1;
+	  mbi++;
+  }
+
+  if (mbi == NumTxMesgBuffers)
+  {
+	  return 0;       // No transmission for you!
+  }
+
+  peak_tx_mailbox_index_ = (peak_tx_mailbox_index_ > mbi ? peak_tx_mailbox_index_ : mbi );
+
+  union TXcsType cs;
+  cs.code = CAN_TXMB_DATAORREMOTE;
+  struct MbTx* mb = &priv->tx[mbi];
+  mb->CS.code = CAN_TXMB_INACTIVE;
+
+  if (0) //FIXME detect Std or Ext id
+  {
+	  cs.ide = 1;
+	  mb->ID.ext = frame->can_id & MaskExtID;
+  }
+  else
+  {
+	  mb->ID.std = frame->can_id & MaskStdID;
+  }
+
+  //cs.rtr = frame.isRemoteTransmissionRequest();
+
+  cs.dlc = frame->can_dlc;
+  //FIXME endian swap instruction or somekind
+  mb->data.b0 = frame->data[0];
+  mb->data.b1 = frame->data[1];
+  mb->data.b2 = frame->data[2];
+  mb->data.b3 = frame->data[3];
+  mb->data.b4 = frame->data[4];
+  mb->data.b5 = frame->data[5];
+  mb->data.b6 = frame->data[6];
+  mb->data.b7 = frame->data[7];
+
+  /*
+   * Registering the pending transmission so we can track its deadline and loopback it as needed
+   */
+  /*TxItem& txi = pending_tx_[mbi];
+  txi.deadline       = tx_deadline;
+  txi.frame          = frame;
+  txi.loopback       = (flags & uavcan::CanIOFlagLoopback) != 0;
+  txi.abort_on_error = (flags & uavcan::CanIOFlagAbortOnError) != 0;
+  txi.pending        = TxItem::busy;*/
+
+  mb->CS = cs; // Go.
+
+  uint32_t regval;
+  regval = getreg32(S32K1XX_CAN0_IMASK1);
+  regval |= mb_bit;
+  putreg32(regval, S32K1XX_CAN0_IMASK1);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Function: s32k1xx_txpoll
+ *
+ * Description:
+ *   The transmitter is available, check if the network has any outgoing
+ *   packets ready to send.  This is a callback from devif_poll().
+ *   devif_poll() may be called:
+ *
+ *   1. When the preceding TX packet send is complete,
+ *   2. When the preceding TX packet send timesout and the interface is reset
+ *   3. During normal TX polling
+ *
+ * Input Parameters:
+ *   dev  - Reference to the NuttX driver state structure
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ * Assumptions:
+ *   May or may not be called from an interrupt handler.  In either case,
+ *   global interrupts are disabled, either explicitly or indirectly through
+ *   interrupt handling logic.
+ *
+ ****************************************************************************/
+
+static int s32k1xx_txpoll(struct net_driver_s *dev)
+{
+  #warning Missing logic
+
+  FAR struct s32k1xx_driver_s *priv =
+    (FAR struct s32k1xx_driver_s *)dev->d_private;
+
+  /* If the polling resulted in data that should be sent out on the network,
+   * the field d_len is set to a value > 0.
+   */
+
+  if (priv->dev.d_len > 0)
+    {
+
+      if (!devif_loopback(&priv->dev))
+        {
+          /* Send the packet */
+
+          s32k1xx_transmit(priv);
+          /*priv->dev.d_buf =
+            (uint8_t *)s32k1xx_swap32((uint32_t)priv->txdesc[priv->txhead].data);*/
+
+          /* Check if there is room in the device to hold another packet. If
+           * not, return a non-zero value to terminate the poll.
+           */
+
+          if (s32k1xx_txringfull(priv))
+            {
+              return -EBUSY;
+            }
+        }
+    }
+
+  /* If zero is returned, the polling will continue until all connections
+   * have been examined.
+   */
+
+  return 0;
+}
+
+/****************************************************************************
+ * Function: s32k1xx_dispatch
+ *
+ * Description:
+ *   A new Rx packet was received; dispatch that packet to the network layer
+ *   as necessary.
+ *
+ * Input Parameters:
+ *   priv  - Reference to the driver state structure
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *   Global interrupts are disabled by interrupt handling logic.
+ *
+ ****************************************************************************/
+
+static inline void s32k1xx_dispatch(FAR struct s32k1xx_driver_s *priv)
+{
+    
+  #warning Missing logic
+}
+
+/****************************************************************************
+ * Function: s32k1xx_receive
+ *
+ * Description:
+ *   An interrupt was received indicating the availability of a new RX packet
+ *
+ * Input Parameters:
+ *   priv  - Reference to the driver state structure
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *   Global interrupts are disabled by interrupt handling logic.
+ *
+ ****************************************************************************/
+
+static void s32k1xx_receive(FAR struct s32k1xx_driver_s *priv)
+{
+  #warning Missing logic
+	printf("FLEXCAN: receive\r\n");
+}
+
+/****************************************************************************
+ * Function: s32k1xx_txdone
+ *
+ * Description:
+ *   An interrupt was received indicating that the last TX packet(s) is done
+ *
+ * Input Parameters:
+ *   priv  - Reference to the driver state structure
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *   Global interrupts are disabled by the watchdog logic.
+ *   The network is locked.
+ *
+ ****************************************************************************/
+
+static void s32k1xx_txdone(FAR struct s32k1xx_driver_s *priv)
+{
+  #warning Missing logic
+
+  uint32_t tx_iflags;
+  tx_iflags = getreg32(S32K1XX_CAN0_IFLAG1) & TXMBMask;
+
+  //FIXME process aborts
+
+  /* Process TX completions */
+
+  uint32_t mb_bit = 1 << NumMBinFiFoAndFilters;
+  for(uint32_t mbi = 0; tx_iflags && mbi < NumTxMesgBuffers; mbi++)
+  {
+      if (tx_iflags & mb_bit)
+      {
+    	  putreg32(mb_bit, S32K1XX_CAN0_IFLAG1);
+          tx_iflags &= ~mb_bit;
+          const bool txok = priv->tx[mbi].CS.code != CAN_TXMB_ABORT;
+          //handleTxMailboxInterrupt(mbi, txok, utc_usec);
+      }
+      mb_bit <<= 1;
+  }
+}
+
+/****************************************************************************
+ * Function: s32k1xx_flexcan_interrupt_work
+ *
+ * Description:
+ *   Perform interrupt related work from the worker thread
+ *
+ * Input Parameters:
+ *   arg - The argument passed when work_queue() was called.
+ *
+ * Returned Value:
+ *   OK on success
+ *
+ * Assumptions:
+ *   The network is locked.
+ *
+ ****************************************************************************/
+
+static void s32k1xx_flexcan_interrupt_work(FAR void *arg)
+{
+  #warning Missing logic
+}
+
+/****************************************************************************
+ * Function: s32k1xx_flexcan_interrupt
+ *
+ * Description:
+ *   Three interrupt sources will vector this this function:
+ *   1. Ethernet MAC transmit interrupt handler
+ *   2. Ethernet MAC receive interrupt handler
+ *   3.
+ *
+ * Input Parameters:
+ *   irq     - Number of the IRQ that generated the interrupt
+ *   context - Interrupt register state save info (architecture-specific)
+ *
+ * Returned Value:
+ *   OK on success
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+
+static int s32k1xx_flexcan_interrupt(int irq, FAR void *context, FAR void *arg)
+{
+  #warning Missing logic
+
+	FAR struct s32k1xx_driver_s *priv = &g_flexcan[0];
+	uint32_t FIFO_IFLAG1 = CAN_FIFO_NE | CAN_FIFO_WARN | CAN_FIFO_OV;
+	uint32_t flags;
+	flags  = getreg32(S32K1XX_CAN0_IFLAG1);
+	flags &= FIFO_IFLAG1;
+
+	if(flags)
+	{
+		s32k1xx_receive(priv);
+	}
+
+	flags  = getreg32(S32K1XX_CAN0_IFLAG1);
+	flags &= TXMBMask;
+
+	if(flags)
+	{
+        s32k1xx_txdone(priv);
+	}
+}
+
+/****************************************************************************
+ * Function: s32k1xx_txtimeout_work
+ *
+ * Description:
+ *   Perform TX timeout related work from the worker thread
+ *
+ * Input Parameters:
+ *   arg - The argument passed when work_queue() as called.
+ *
+ * Returned Value:
+ *   OK on success
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static void s32k1xx_txtimeout_work(FAR void *arg)
+{
+  #warning Missing logic
+	  printf("FLEXCAN: tx timeout work\r\n");
+}
+
+/****************************************************************************
+ * Function: s32k1xx_txtimeout_expiry
+ *
+ * Description:
+ *   Our TX watchdog timed out.  Called from the timer interrupt handler.
+ *   The last TX never completed.  Reset the hardware and start again.
+ *
+ * Input Parameters:
+ *   argc - The number of available arguments
+ *   arg  - The first argument
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *   Global interrupts are disabled by the watchdog logic.
+ *
+ ****************************************************************************/
+
+static void s32k1xx_txtimeout_expiry(int argc, uint32_t arg, ...)
+{
+  #warning Missing logic
+	  printf("FLEXCAN: tx timeout expiry\r\n");
+}
+
+/****************************************************************************
+ * Function: s32k1xx_poll_work
+ *
+ * Description:
+ *   Perform periodic polling from the worker thread
+ *
+ * Input Parameters:
+ *   arg - The argument passed when work_queue() as called.
+ *
+ * Returned Value:
+ *   OK on success
+ *
+ * Assumptions:
+ *   The network is locked.
+ *
+ ****************************************************************************/
+
+static void s32k1xx_poll_work(FAR void *arg)
+{
+  #warning Missing logic
+	  //printf("FLEXCAN: poll work\r\n");
+
+	  FAR struct s32k1xx_driver_s *priv = (FAR struct s32k1xx_driver_s *)arg;
+
+	  /* Check if there is there is a transmission in progress.  We cannot
+	   * perform the TX poll if he are unable to accept another packet for
+	   * transmission.
+	   */
+
+	  net_lock();
+	  if (1) //!s32k1xx_txringfull(priv))
+	    {
+	      /* If so, update TCP timing states and poll the network for new XMIT
+	       * data. Hmmm.. might be bug here.  Does this mean if there is a
+	       * transmit in progress, we will missing TCP time state updates?
+	       */
+
+	      devif_timer(&priv->dev, S32K1XX_WDDELAY, s32k1xx_txpoll);
+	    }
+
+	  /* Setup the watchdog poll timer again in any case */
+
+	  wd_start(priv->txpoll, S32K1XX_WDDELAY, s32k1xx_polltimer_expiry,
+	           1, (wdparm_t)priv);
+	  net_unlock();
+
+}
+
+/****************************************************************************
+ * Function: s32k1xx_polltimer_expiry
+ *
+ * Description:
+ *   Periodic timer handler.  Called from the timer interrupt handler.
+ *
+ * Input Parameters:
+ *   argc - The number of available arguments
+ *   arg  - The first argument
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *   Global interrupts are disabled by the watchdog logic.
+ *
+ ****************************************************************************/
+
+static void s32k1xx_polltimer_expiry(int argc, uint32_t arg, ...)
+{
+  #warning Missing logic
+  FAR struct s32k1xx_driver_s *priv = (FAR struct s32k1xx_driver_s *)arg;
+
+  /* Schedule to perform the poll processing on the worker thread. */
+
+  work_queue(ETHWORK, &priv->pollwork, s32k1xx_poll_work, priv, 0);
+}
+
+static void s32k1xx_setfreeze(uint32_t freeze)
+{
+	uint32_t regval;
+	if(freeze)
+	{
+		/* Enter freeze mode */
+		regval  = getreg32(S32K1XX_CAN0_MCR);
+		regval |= (CAN_MCR_HALT | CAN_MCR_FRZ);
+		putreg32(regval, S32K1XX_CAN0_MCR);
+	}
+	else
+	{
+		/* Exit freeze mode */
+		regval  = getreg32(S32K1XX_CAN0_MCR);
+		regval &= ~(CAN_MCR_HALT | CAN_MCR_FRZ);
+		putreg32(regval, S32K1XX_CAN0_MCR);
+	}
+}
+
+static uint32_t s32k1xx_waitmcr_change(uint32_t mask, uint32_t target_state)
+{
+	const unsigned Timeout = 1000;
+	for (unsigned wait_ack = 0; wait_ack < Timeout; wait_ack++)
+	{
+		const bool state = (getreg32(S32K1XX_CAN0_MCR) & mask) != 0;
+		if (state == target_state)
+		{
+			return true;
+		}
+		up_udelay(10);
+	}
+	return false;
+}
+
+static uint32_t s32k1xx_waitfreezeack_change(uint32_t target_state)
+{
+    return s32k1xx_waitmcr_change(CAN_MCR_FRZACK, target_state);
+}
+
+
+/****************************************************************************
+ * Function: s32k1xx_ifup
+ *
+ * Description:
+ *   NuttX Callback: Bring up the Ethernet interface when an IP address is
+ *   provided
+ *
+ * Input Parameters:
+ *   dev  - Reference to the NuttX driver state structure
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static int s32k1xx_ifup(struct net_driver_s *dev)
+{
+  FAR struct s32k1xx_driver_s *priv =
+	(FAR struct s32k1xx_driver_s *)dev->d_private;
+  uint32_t regval;
+
+  #warning Missing logic
+  printf("FLEXCAN: test ifup\r\n");
+
+  /* initialize CAN device */
+  //FIXME we only support a single can device for now
+
+
+  regval  = getreg32(S32K1XX_CAN0_MCR);
+  regval |= CAN_MCR_MDIS;
+  putreg32(regval, S32K1XX_CAN0_MCR);
+
+  /* Set SYS_CLOCK src */
+  regval  = getreg32(S32K1XX_CAN0_CTRL1);
+  regval |= CAN_CTRL1_CLKSRC;
+  putreg32(regval, S32K1XX_CAN0_CTRL1);
+
+  regval  = getreg32(S32K1XX_CAN0_MCR);
+  regval &= ~(CAN_MCR_MDIS);
+  putreg32(regval, S32K1XX_CAN0_MCR);
+
+
+  regval  = getreg32(S32K1XX_CAN0_MCR);
+  regval |= CAN_MCR_RFEN | CAN_MCR_SLFWAK | CAN_MCR_WRNEN | CAN_MCR_SRXDIS
+		  | CAN_MCR_IRMQ | CAN_MCR_AEN |
+		  (((HWMaxMB - 1) << CAN_MCR_MAXMB_SHIFT) & CAN_MCR_MAXMB_MASK);
+  putreg32(regval, S32K1XX_CAN0_MCR);
+
+  regval  = CAN_CTRL2_RRS | CAN_CTRL2_EACEN | CAN_CTRL2_RFFN_16MB; //FIXME TASD
+  putreg32(regval, S32K1XX_CAN0_CTRL2);
+
+  /* Enter freeze mode */
+  s32k1xx_setfreeze(1);
+  if(!s32k1xx_waitfreezeack_change(1))
+  {
+	  printf("FLEXCAN: freeze fail\r\n");
+	  return -1;
+  }
+
+  /*regval  = getreg32(S32K1XX_CAN0_CTRL1);
+  regval |= ((0  << CAN_CTRL1_PRESDIV_SHIFT) & CAN_CTRL1_PRESDIV_MASK)
+		  | ((46 << CAN_CTRL1_ROPSEG_SHIFT) & CAN_CTRL1_ROPSEG_MASK)
+	      | ((18 << CAN_CTRL1_PSEG1_SHIFT) & CAN_CTRL1_PSEG1_MASK)
+		  | ((12 << CAN_CTRL1_PSEG2_SHIFT) & CAN_CTRL1_PSEG2_MASK)
+		  | ((12 << CAN_CTRL1_RJW_SHIFT) & CAN_CTRL1_RJW_MASK)
+		  | CAN_CTRL1_ERRMSK
+		  | CAN_CTRL1_TWRNMSK
+		  | CAN_CTRL1_RWRNMSK;
+
+  putreg32(regval, S32K1XX_CAN0_CTRL1);*/
+
+  /* CAN Bit Timing (CBT) configuration for a nominal phase of 1 Mbit/s
+   * with 80 time quantas,in accordance with Bosch 2012 specification,
+   * sample point at 83.75% */
+  regval  = getreg32(S32K1XX_CAN0_CBT);
+  regval |= CAN_CBT_BTF |     /* Enable extended bit timing configurations for CAN-FD
+                                      for setting up separetely nominal and data phase */
+            CAN_CBT_EPRESDIV(0) |  /* Prescaler divisor factor of 1 */
+            CAN_CBT_EPROPSEG(46) | /* Propagation segment of 47 time quantas */
+            CAN_CBT_EPSEG1(18) |   /* Phase buffer segment 1 of 19 time quantas */
+            CAN_CBT_EPSEG2(12) |   /* Phase buffer segment 2 of 13 time quantas */
+            CAN_CBT_ERJW(12);      /* Resynchronization jump width same as PSEG2 */
+  putreg32(regval, S32K1XX_CAN0_CBT);
+
+#ifdef CAN_FD
+
+  /* Enable CAN FD feature */
+  regval  = getreg32(S32K1XX_CAN0_MCR);
+  regval |= CAN_MCR_FDEN;
+  putreg32(regval, S32K1XX_CAN0_MCR);
+
+  /* CAN-FD Bit Timing (FDCBT) for a data phase of 4 Mbit/s with 20 time quantas,
+                 in accordance with Bosch 2012 specification, sample point at 75% */
+  regval  = getreg32(S32K1XX_CAN0_FDCBT);
+  regval |= CAN_FDCBT_FPRESDIV(0) | /* Prescaler divisor factor of 1 */
+		  CAN_FDCBT_FPROPSEG(7) | /* Propagation semgment of 7 time quantas
+                                                              (only register that doesn't add 1) */
+		  CAN_FDCBT_FPSEG1(6) |   /* Phase buffer segment 1 of 7 time quantas */
+		  CAN_FDCBT_FPSEG2(4) |   /* Phase buffer segment 2 of 5 time quantas */
+		  CAN_FDCBT_FRJW(4);      /* Resynchorinzation jump width same as PSEG2 */
+  putreg32(regval, S32K1XX_CAN0_FDCBT);
+
+  /* Additional CAN-FD configurations */
+  regval  = getreg32(S32K1XX_CAN0_FDCTRL);
+  regval |= CAN_FDCTRL_FDRATE | /* Enable bit rate switch in data phase of frame */
+		  CAN_FDCTRL_TDCEN |  /* Enable transceiver delay compensation */
+		  CAN_FDCTRL_TDCOFF(5) |   /* Setup 5 cycles for data phase sampling delay */
+		  CAN_FDCTRL_MBDSR0(3);    /* Setup 64 bytes per message buffer (7 MB's) */
+  putreg32(regval, S32K1XX_CAN0_FDCTRL);
+
+  regval  = getreg32(S32K1XX_CAN0_CTRL2);
+  regval |= CAN_CTRL2_ISOCANFDEN;
+  putreg32(regval, S32K1XX_CAN0_CTRL2);
+#endif
+
+
+  /* Filtering catchall */
+  putreg32(0, S32K1XX_CAN0_RXFGMASK);
+
+  /* Iniatilize all MB rx and tx */
+  /*for(int i = 0; i < HWMaxMB; i++)
+  {
+	  priv->rx[i].CS.cs = 0x0;
+	  priv->rx[i].ID.w = 0x0;
+	  priv->rx[i].data.l = 0x0;
+	  priv->rx[i].data.h = 0x0;
+  }*/
+
+  //FIXME max mb
+  for(int i = 0; i < HWMaxMB; i++)
+  {
+	  putreg32(0,S32K1XX_CAN0_RXIMR(i));
+  }
+
+  putreg32(0,S32K1XX_CAN0_RXIMR0);
+  putreg32(0,S32K1XX_CAN0_RXIMR1);
+  putreg32(0,S32K1XX_CAN0_RXIMR2);
+  putreg32(0,S32K1XX_CAN0_RXIMR3);
+  putreg32(0,S32K1XX_CAN0_RXIMR4);
+  putreg32(0,S32K1XX_CAN0_RXIMR5);
+  putreg32(0,S32K1XX_CAN0_RXIMR6);
+  putreg32(0,S32K1XX_CAN0_RXIMR7);
+  putreg32(0,S32K1XX_CAN0_RXIMR8);
+  putreg32(0,S32K1XX_CAN0_RXIMR9);
+  putreg32(0,S32K1XX_CAN0_RXIMR10);
+  putreg32(0,S32K1XX_CAN0_RXIMR11);
+  putreg32(0,S32K1XX_CAN0_RXIMR12);
+  putreg32(0,S32K1XX_CAN0_RXIMR13);
+  putreg32(0,S32K1XX_CAN0_RXIMR14);
+  putreg32(0,S32K1XX_CAN0_RXIMR15);
+
+  putreg32(CAN_IFLAG1(1) | TXMBMask, S32K1XX_CAN0_IFLAG1); //FIXME dynamic MXMB
+  putreg32(CAN_IFLAG1(1), S32K1XX_CAN0_IMASK1);
+
+
+  /* Exit freeze mode */
+  s32k1xx_setfreeze(0);
+  if(!s32k1xx_waitfreezeack_change(0))
+  {
+	  printf("FLEXCAN: unfreeze fail\r\n");
+	  return -1;
+  }
+
+
+  /* Set and activate a timer process */
+
+  wd_start(priv->txpoll, S32K1XX_WDDELAY, s32k1xx_polltimer_expiry, 1,
+           (wdparm_t)priv);
+
+  priv->bifup = true;
+
+  priv->dev.d_buf = &g_desc_pool;
+
+  /* Set interrupts */
+  up_enable_irq(S32K1XX_IRQ_CAN0_BUS);
+  up_enable_irq(S32K1XX_IRQ_CAN0_ERROR);
+  up_enable_irq(S32K1XX_IRQ_CAN0_LPRX);
+  up_enable_irq(S32K1XX_IRQ_CAN0_0_15);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Function: s32k1xx_ifdown
+ *
+ * Description:
+ *   NuttX Callback: Stop the interface.
+ *
+ * Input Parameters:
+ *   dev  - Reference to the NuttX driver state structure
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static int s32k1xx_ifdown(struct net_driver_s *dev)
+{
+  #warning Missing logic
+  return OK;
+}
+
+/****************************************************************************
+ * Function: s32k1xx_txavail_work
+ *
+ * Description:
+ *   Perform an out-of-cycle poll on the worker thread.
+ *
+ * Input Parameters:
+ *   arg - Reference to the NuttX driver state structure (cast to void*)
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *   Called on the higher priority worker thread.
+ *
+ ****************************************************************************/
+
+static void s32k1xx_txavail_work(FAR void *arg)
+{
+	  FAR struct s32k1xx_driver_s *priv = (FAR struct s32k1xx_driver_s *)arg;
+
+	  /* Ignore the notification if the interface is not yet up */
+
+	  net_lock();
+	  if (priv->bifup)
+	    {
+	      /* Check if there is room in the hardware to hold another outgoing
+	       * packet.
+	       */
+
+	      if (!s32k1xx_txringfull(priv))
+	        {
+	          /* No, there is space for another transfer.  Poll the network for
+	           * new XMIT data.
+	           */
+
+	          devif_poll(&priv->dev, s32k1xx_txpoll);
+	        }
+	    }
+
+	  net_unlock();
+}
+
+/****************************************************************************
+ * Function: s32k1xx_txavail
+ *
+ * Description:
+ *   Driver callback invoked when new TX data is available.  This is a
+ *   stimulus perform an out-of-cycle poll and, thereby, reduce the TX
+ *   latency.
+ *
+ * Input Parameters:
+ *   dev  - Reference to the NuttX driver state structure
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *   Called in normal user mode
+ *
+ ****************************************************************************/
+
+static int s32k1xx_txavail(struct net_driver_s *dev)
+{
+  FAR struct s32k1xx_driver_s *priv =
+    (FAR struct s32k1xx_driver_s *)dev->d_private;
+
+  /* Is our single work structure available?  It may not be if there are
+   * pending interrupt actions and we will have to ignore the Tx
+   * availability action.
+   */
+
+  if (work_available(&priv->pollwork))
+    {
+      /* Schedule to serialize the poll on the worker thread. */
+
+      work_queue(ETHWORK, &priv->pollwork, s32k1xx_txavail_work, priv, 0);
+    }
+
+  return OK;
+}
+
+
+/****************************************************************************
+ * Function: s32k1xx_ioctl
+ *
+ * Description:
+ *   PHY ioctl command handler
+ *
+ * Input Parameters:
+ *   dev  - Reference to the NuttX driver state structure
+ *   cmd  - ioctl command
+ *   arg  - Argument accompanying the command
+ *
+ * Returned Value:
+ *   Zero (OK) on success; a negated errno value on failure.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NETDEV_IOCTL
+static int s32k1xx_ioctl(struct net_driver_s *dev, int cmd,
+                         unsigned long arg)
+{
+  int ret;
+
+  switch (cmd)
+    {
+      default:
+        ret = -ENOTTY;
+        break;
+    }
+
+  return ret;
+}
+#endif /* CONFIG_NETDEV_IOCTL */
+
+
+/****************************************************************************
+ * Function: s32k1xx_initbuffers
+ *
+ * Description:
+ *   Initialize FLEXCAN buffers and descriptors
+ *
+ * Input Parameters:
+ *   priv - Reference to the private FLEXCAN driver state structure
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static void s32k1xx_initbuffers(struct s32k1xx_driver_s *priv)
+{
+  #warning Missing logic
+}
+
+/****************************************************************************
+ * Function: s32k1xx_reset
+ *
+ * Description:
+ *   Put the EMAC in the non-operational, reset state
+ *
+ * Input Parameters:
+ *   priv - Reference to the private FLEXCAN driver state structure
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static void s32k1xx_reset(struct s32k1xx_driver_s *priv)
+{
+  unsigned int i;
+
+  /* Set the reset bit and clear the enable bit */
+
+  
+  #warning Missing logic
+
+  /* Wait at least 8 clock cycles */
+
+  for (i = 0; i < 10; i++)
+    {
+      asm volatile ("nop");
+    }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Function: s32k1xx_netinitialize
+ *
+ * Description:
+ *   Initialize the Ethernet controller and driver
+ *
+ * Input Parameters:
+ *   intf - In the case where there are multiple EMACs, this value
+ *          identifies which EMAC is to be initialized.
+ *
+ * Returned Value:
+ *   OK on success; Negated errno on failure.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int s32k1xx_netinitialize(int intf)
+{
+  struct s32k1xx_driver_s *priv;
+  int ret;
+
+  //FIXME dynamic board config
+  s32k1xx_pinconfig(PIN_CAN0_TX_4);
+  s32k1xx_pinconfig(PIN_CAN0_RX_4);
+
+  priv = &g_flexcan[intf];
+
+  ninfo("initialize\r\n");
+
+  /* Get the interface structure associated with this interface number. */
+
+    #warning Missing logic
+
+
+  /* Attach the flexcan interrupt handler */
+  if (irq_attach(S32K1XX_IRQ_CAN0_BUS, s32k1xx_flexcan_interrupt, NULL))
+    {
+      /* We could not attach the ISR to the interrupt */
+
+      nerr("ERROR: Failed to attach CAN bus IRQ\n");
+      return -EAGAIN;
+    }
+  if (irq_attach(S32K1XX_IRQ_CAN0_ERROR, s32k1xx_flexcan_interrupt, NULL))
+    {
+      /* We could not attach the ISR to the interrupt */
+
+      nerr("ERROR: Failed to attach CAN error IRQ\n");
+      return -EAGAIN;
+    }
+  if (irq_attach(S32K1XX_IRQ_CAN0_LPRX, s32k1xx_flexcan_interrupt, NULL))
+    {
+      /* We could not attach the ISR to the interrupt */
+
+      nerr("ERROR: Failed to attach CAN LPRX IRQ\n");
+      return -EAGAIN;
+    }
+  if (irq_attach(S32K1XX_IRQ_CAN0_0_15, s32k1xx_flexcan_interrupt, NULL))
+    {
+      /* We could not attach the ISR to the interrupt */
+
+      nerr("ERROR: Failed to attach CAN OR'ed Message buffer (0-15) IRQ\n");
+      return -EAGAIN;
+    }
+
+  /* Initialize the driver structure */
+
+  memset(priv, 0, sizeof(struct s32k1xx_driver_s));
+  priv->dev.d_ifup    = s32k1xx_ifup;     /* I/F up (new IP address) callback */
+  priv->dev.d_ifdown  = s32k1xx_ifdown;   /* I/F down callback */
+  priv->dev.d_txavail = s32k1xx_txavail;  /* New TX data callback */
+#ifdef CONFIG_NETDEV_IOCTL
+  priv->dev.d_ioctl   = s32k1xx_ioctl;    /* Support PHY ioctl() calls */
+#endif
+  priv->dev.d_private = (void *)g_flexcan;   /* Used to recover private state from dev */
+
+  /* Create a watchdog for timing polling for and timing of transmissions */
+  priv->txpoll        = wd_create();      /* Create periodic poll timer */
+  priv->txtimeout     = wd_create();      /* Create TX timeout timer */
+  priv->rx            = (struct MbRx *)(S32K1XX_CAN0_MB);
+  priv->tx            = (struct MbTx *)(S32K1XX_CAN0_MB + (sizeof(struct MbRx)
+		                                * S32K1XX_FLEXCAN_FIRST_TX_MB) );
+
+  /* Put the interface in the down state.  This usually amounts to resetting
+   * the device and/or calling s32k1xx_ifdown().
+   */
+
+  ninfo("callbacks done\r\n");
+
+  s32k1xx_ifdown(&priv->dev);
+
+  /* Register the device with the OS so that socket IOCTLs can be performed */
+
+  netdev_register(&priv->dev, NET_LL_CAN);
+
+  UNUSED(ret);
+  return OK;
+}
+
+/****************************************************************************
+ * Name: up_netinitialize
+ *
+ * Description:
+ *   Initialize the first network interface.  If there are more than one
+ *   interface in the chip, then board-specific logic will have to provide
+ *   this function to determine which, if any, Ethernet controllers should
+ *   be initialized.
+ *
+ ****************************************************************************/
+
+//FIXME CONFIG_S32K1XX_FLEXCAN_NETHIFS == 1 && 
+
+#if !defined(CONFIG_NETDEV_LATEINIT)
+void up_netinitialize(void)
+{
+  s32k1xx_netinitialize(0);
+}
+#endif
+
+#endif /* CONFIG_S32K1XX_FLEXCAN */
diff --git a/net/devif/devif_pktsend.c b/arch/arm/src/s32k1xx/s32k1xx_flexcan.h
similarity index 54%
copy from net/devif/devif_pktsend.c
copy to arch/arm/src/s32k1xx/s32k1xx_flexcan.h
index b041b2f..9dfe681 100644
--- a/net/devif/devif_pktsend.c
+++ b/arch/arm/src/s32k1xx/s32k1xx_flexcan.h
@@ -1,7 +1,7 @@
-/****************************************************************************
- * net/devif/devif_pktsend.c
+/************************************************************************************
+ * arch/arm/src/s32k1xx/s32k1xx_flexcan.h
  *
- *   Copyright (C) 2014 Gregory Nutt. All rights reserved.
+ *   Copyright (C) 2018 Gregory Nutt. All rights reserved.
  *   Author: Gregory Nutt <gn...@nuttx.org>
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,83 +31,87 @@
  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  *
- ****************************************************************************/
+ ************************************************************************************/
 
-/****************************************************************************
+#ifndef __ARCH_ARM_SRC_S32K1XX_S32K1XX_FLEXCAN_H
+#define __ARCH_ARM_SRC_S32K1XX_S32K1XX_FLEXCAN_H
+
+/************************************************************************************
  * Included Files
- ****************************************************************************/
+ ************************************************************************************/
 
 #include <nuttx/config.h>
 
-#include <string.h>
-#include <assert.h>
-#include <debug.h>
-
-#include <nuttx/net/netdev.h>
+#include "hardware/s32k1xx_flexcan.h"
 
-#ifdef CONFIG_NET_PKT
+#ifdef CONFIG_S32K1XX_FLEXCAN
 
-/****************************************************************************
+/************************************************************************************
  * Pre-processor Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Private Type Declarations
- ****************************************************************************/
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
+ ************************************************************************************/
 
-/****************************************************************************
- * Public Constant Data
- ****************************************************************************/
 
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-
-/****************************************************************************
- * Private Constant Data
- ****************************************************************************/
+/************************************************************************************
+ * Public Functions
+ ************************************************************************************/
 
-/****************************************************************************
- * Private Data
- ****************************************************************************/
+#ifndef __ASSEMBLY__
 
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
 
-/****************************************************************************
- * Name: devif_pkt_send
+/************************************************************************************
+ * Function: up_netinitialize
  *
  * Description:
- *   Called from socket logic in order to send a raw packet in response to
- *   an xmit or poll request from the network interface driver.
+ *   Initialize the first network interface.  If there are more than one
+ *   interface in the chip, then board-specific logic will have to provide
+ *   this function to determine which, if any, Ethernet controllers should
+ *   be initialized.  Also prototyped in up_internal.h.
  *
- *   This is almost identical to calling devif_send() except that the data to
- *   be sent is copied into dev->d_buf (vs. dev->d_appdata), since there is
- *   no header on the data.
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   OK on success; Negated errno on failure.
  *
  * Assumptions:
- *   Called with the network locked.
+ *   Called very early in the initialization sequence.
  *
- ****************************************************************************/
-
-void devif_pkt_send(FAR struct net_driver_s *dev, FAR const void *buf,
-                    unsigned int len)
-{
-  DEBUGASSERT(dev && len > 0 && len < NETDEV_PKTSIZE(dev));
+ ************************************************************************************/
 
-  /* Copy the data into the device packet buffer */
+void up_netinitialize(void);
 
-  memcpy(dev->d_buf, buf, len);
+/************************************************************************************
+ * Function: s32k1xx_phy_boardinitialize
+ *
+ * Description:
+ *   Some boards require specialized initialization of the PHY before it can be
+ *   used.  This may include such things as configuring GPIOs, resetting the PHY,
+ *   etc.  If CONFIG_S32K1XX_FLEXCAN_PHYINIT is defined in the configuration then the
+ *   board specific logic must provide s32k1xx_phyinitialize();  The i.MX RT Ethernet
+ *   driver will call this function one time before it first uses the PHY.
+ *
+ * Input Parameters:
+ *   intf - Always zero for now.
+ *
+ * Returned Value:
+ *   OK on success; Negated errno on failure.
+ *
+ ************************************************************************************/
 
-  /* Set the number of bytes to send */
 
-  dev->d_len    = len;
-  dev->d_sndlen = len;
+#undef EXTERN
+#if defined(__cplusplus)
 }
+#endif
 
-#endif /* CONFIG_NET_PKT */
+#endif /* __ASSEMBLY__ */
+#endif /* CONFIG_S32K1XX_FLEXCAN */
+#endif /* __ARCH_ARM_SRC_S32K1XX_S32K1XX_FLEXCAN_H */
diff --git a/include/nuttx/can.h b/include/nuttx/can.h
new file mode 100644
index 0000000..fd86b74
--- /dev/null
+++ b/include/nuttx/can.h
@@ -0,0 +1,279 @@
+/************************************************************************************
+ * include/nuttx/can/can.h
+ *
+ *   Copyright (C) 2008, 2009, 2011-2012, 2015-2017, 2019 Gregory Nutt. All rights
+ *     reserved.
+ *   Author: Gregory Nutt <gn...@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************************/
+
+#ifndef __INCLUDE_NUTTX_CAN_CAN_H
+#define __INCLUDE_NUTTX_CAN_CAN_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#ifdef CONFIG_CAN_TXREADY
+#  include <nuttx/wqueue.h>
+#endif
+
+#ifdef CONFIG_NET_CAN
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+
+/* Ioctl Commands *******************************************************************/
+
+/* Ioctl commands supported by the upper half CAN driver.
+ *
+ * CANIOC_RTR:
+ *   Description:  Send the remote transmission request and wait for the response.
+ *   Argument:     A reference to struct canioc_rtr_s
+ *
+ * Ioctl commands that may or may not be supported by the lower half CAN driver.
+ *
+ * CANIOC_ADD_STDFILTER:
+ *   Description:    Add an address filter for a standard 11 bit address.
+ *   Argument:       A reference to struct canioc_stdfilter_s
+ *   Returned Value: A non-negative filter ID is returned on success.
+ *                   Otherwise -1 (ERROR) is returned with the errno
+ *                   variable set to indicate the nature of the error.
+ *   Dependencies:   None
+ *
+ * CANIOC_ADD_EXTFILTER:
+ *   Description:    Add an address filter for a extended 29 bit address.
+ *   Argument:       A reference to struct canioc_extfilter_s
+ *   Returned Value: A non-negative filter ID is returned on success.
+ *                   Otherwise -1 (ERROR) is returned with the errno
+ *                   variable set to indicate the nature of the error.
+ *   Dependencies:   Requires CONFIG_CAN_EXTID=y
+ *
+ * CANIOC_DEL_STDFILTER:
+ *   Description:    Remove an address filter for a standard 11 bit address.
+ *   Argument:       The filter index previously returned by the
+ *                   CANIOC_ADD_STDFILTER command
+ *   Returned Value: Zero (OK) is returned on success.  Otherwise -1 (ERROR)
+ *                   is returned with the errno variable set to indicate the
+ *                   nature of the error.
+ *   Dependencies:   None
+ *
+ * CANIOC_DEL_EXTFILTER:
+ *   Description:    Remove an address filter for a standard 29 bit address.
+ *   Argument:       The filter index previously returned by the
+ *                   CANIOC_ADD_EXTFILTER command
+ *   Returned Value: Zero (OK) is returned on success.  Otherwise -1 (ERROR)
+ *                   is returned with the errno variable set to indicate the
+ *                   nature of the error.
+ *   Dependencies:   Requires CONFIG_CAN_EXTID=y
+ *
+ * CANIOC_GET_BITTIMING:
+ *   Description:    Return the current bit timing settings
+ *   Argument:       A pointer to a write-able instance of struct
+ *                   canioc_bittiming_s in which current bit timing values
+ *                   will be returned.
+ *   Returned Value: Zero (OK) is returned on success.  Otherwise -1 (ERROR)
+ *                   is returned with the errno variable set to indicate the
+ *                   nature of the error.
+ *   Dependencies:   None
+ *
+ * CANIOC_SET_BITTIMING:
+ *   Description:    Set new current bit timing values
+ *   Argument:       A pointer to a read-able instance of struct
+ *                   canioc_bittiming_s in which the new bit timing values
+ *                   are provided.
+ *   Returned Value: Zero (OK) is returned on success.  Otherwise -1 (ERROR)
+ *                   is returned with the errno variable set to indicate the
+ *                   nature of the error.
+ *   Dependencies:   None
+ *
+ * CANIOC_GET_CONNMODES:
+ *   Description:    Get the current bus connection modes
+ *   Argument:       A pointer to a write-able instance of struct
+ *                   canioc_connmodes_s in which the new bus modes will be returned.
+ *   Returned Value: Zero (OK) is returned on success.  Otherwise -1 (ERROR)
+ *                   is returned with the errno variable set to indicate the
+ *                   nature of the error.
+ *   Dependencies:   None
+ *
+ * CANIOC_SET_CONNMODES:
+ *   Description:    Set new bus connection modes values
+ *   Argument:       A pointer to a read-able instance of struct
+ *                   canioc_connmodes_s in which the new bus modes are provided.
+ *   Returned Value: Zero (OK) is returned on success.  Otherwise -1 (ERROR)
+ *                   is returned with the errno variable set to indicate the
+ *                   nature of the error.
+ *   Dependencies:   None
+ *
+ * CANIOC_BUSOFF_RECOVERY:
+ *   Description:    Initiates the BUS-OFF recovery sequence
+ *   Argument:       None
+ *   Returned Value: Zero (OK) is returned on success.  Otherwise -1 (ERROR)
+ *                   is returned with the errno variable set to indicate the
+ *                   nature of the error.
+ *   Dependencies:   None
+ */
+
+#define CANIOC_RTR                _CANIOC(1)
+#define CANIOC_GET_BITTIMING      _CANIOC(2)
+#define CANIOC_SET_BITTIMING      _CANIOC(3)
+#define CANIOC_ADD_STDFILTER      _CANIOC(4)
+#define CANIOC_ADD_EXTFILTER      _CANIOC(5)
+#define CANIOC_DEL_STDFILTER      _CANIOC(6)
+#define CANIOC_DEL_EXTFILTER      _CANIOC(7)
+#define CANIOC_GET_CONNMODES      _CANIOC(8)
+#define CANIOC_SET_CONNMODES      _CANIOC(9)
+#define CANIOC_BUSOFF_RECOVERY    _CANIOC(10)
+
+#define CAN_FIRST                 0x0001         /* First common command */
+#define CAN_NCMDS                 10             /* Ten common commands */
+
+/* User defined ioctl commands are also supported. These will be forwarded
+ * by the upper-half CAN driver to the lower-half CAN driver via the co_ioctl()
+ * method fo the CAN lower-half interface.  However, the lower-half driver
+ * must reserve a block of commands as follows in order prevent IOCTL
+ * command numbers from overlapping.
+ *
+ * This is generally done as follows.  The first reservation for CAN driver A would
+ * look like:
+ *
+ *   CAN_A_FIRST                 (CAN_FIRST + CAN_NCMDS)     <- First command
+ *   CAN_A_NCMDS                 42                          <- Number of commands
+ *
+ * IOCTL commands for CAN driver A would then be defined in a CAN A header file like:
+ *
+ *   CANIOC_A_CMD1               _CANIOC(CAN_A_FIRST+0)
+ *   CANIOC_A_CMD2               _CANIOC(CAN_A_FIRST+1)
+ *   CANIOC_A_CMD3               _CANIOC(CAN_A_FIRST+2)
+ *   ...
+ *   CANIOC_A_CMD42              _CANIOC(CAN_A_FIRST+41)
+ *
+ * The next reservation would look like:
+ *
+ *   CAN_B_FIRST                 (CAN_A_FIRST + CAN_A_NCMDS) <- Next command
+ *   CAN_B_NCMDS                 77                          <- Number of commands
+ */
+
+/************************************************************************************
+ * Public Types
+ ************************************************************************************/
+
+typedef uint32_t canid_t;
+
+/* CAN payload length and DLC definitions according to ISO 11898-1 */
+#define CAN_MAX_DLC 8
+#define CAN_MAX_DLEN 8
+
+/* CAN FD payload length and DLC definitions according to ISO 11898-7 */
+#define CANFD_MAX_DLC 15
+#define CANFD_MAX_DLEN 64
+
+
+/**
+ * struct can_frame - basic CAN frame structure
+ * @can_id:  CAN ID of the frame and CAN_*_FLAG flags, see canid_t definition
+ * @can_dlc: frame payload length in byte (0 .. 8) aka data length code
+ *           N.B. the DLC field from ISO 11898-1 Chapter 8.4.2.3 has a 1:1
+ *           mapping of the 'data length code' to the real payload length
+ * @__pad:   padding
+ * @__res0:  reserved / padding
+ * @__res1:  reserved / padding
+ * @data:    CAN frame payload (up to 8 byte)
+ */
+struct can_frame {
+	canid_t can_id;  /* 32 bit CAN_ID + EFF/RTR/ERR flags */
+	uint8_t    can_dlc; /* frame payload length in byte (0 .. CAN_MAX_DLEN) */
+	uint8_t    __pad;   /* padding */
+	uint8_t    __res0;  /* reserved / padding */
+	uint8_t    __res1;  /* reserved / padding */
+	uint8_t    data[CAN_MAX_DLEN] __attribute__((aligned(8)));
+};
+
+/*
+ * defined bits for canfd_frame.flags
+ *
+ * The use of struct canfd_frame implies the Extended Data Length (EDL) bit to
+ * be set in the CAN frame bitstream on the wire. The EDL bit switch turns
+ * the CAN controllers bitstream processor into the CAN FD mode which creates
+ * two new options within the CAN FD frame specification:
+ *
+ * Bit Rate Switch - to indicate a second bitrate is/was used for the payload
+ * Error State Indicator - represents the error state of the transmitting node
+ *
+ * As the CANFD_ESI bit is internally generated by the transmitting CAN
+ * controller only the CANFD_BRS bit is relevant for real CAN controllers when
+ * building a CAN FD frame for transmission. Setting the CANFD_ESI bit can make
+ * sense for virtual CAN interfaces to test applications with echoed frames.
+ */
+#define CANFD_BRS 0x01 /* bit rate switch (second bitrate for payload data) */
+#define CANFD_ESI 0x02 /* error state indicator of the transmitting node */
+
+/**
+ * struct canfd_frame - CAN flexible data rate frame structure
+ * @can_id: CAN ID of the frame and CAN_*_FLAG flags, see canid_t definition
+ * @len:    frame payload length in byte (0 .. CANFD_MAX_DLEN)
+ * @flags:  additional flags for CAN FD
+ * @__res0: reserved / padding
+ * @__res1: reserved / padding
+ * @data:   CAN FD frame payload (up to CANFD_MAX_DLEN byte)
+ */
+struct canfd_frame {
+	canid_t can_id;  /* 32 bit CAN_ID + EFF/RTR/ERR flags */
+	uint8_t    len;     /* frame payload length in byte */
+	uint8_t    flags;   /* additional flags for CAN FD */
+	uint8_t    __res0;  /* reserved / padding */
+	uint8_t    __res1;  /* reserved / padding */
+	uint8_t    data[CANFD_MAX_DLEN] __attribute__((aligned(8)));
+};
+
+
+/************************************************************************************
+ * Public Function Prototypes
+ ************************************************************************************/
+
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* CONFIG_CAN */
+#endif /* __INCLUDE_NUTTX_CAN_CAN_H */
diff --git a/include/nuttx/net/can.h b/include/nuttx/net/can.h
new file mode 100644
index 0000000..d426c7b
--- /dev/null
+++ b/include/nuttx/net/can.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+ * include/nuttx/net/ethernt.h
+ * Macros and definitions for the Ethernet link layer.
+ *
+ *   Copyright (C) 2007, 2009-2012, 2015 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <gn...@nuttx.org>
+ *
+ * Derived from uIP with has a similar BSD-styple license:
+ *
+ *   Author: Adam Dunkels <ad...@dunkels.com>
+ *   Copyright (c) 2001-2003, Adam Dunkels.
+ *   All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+#ifndef __INCLUDE_NUTTX_NET_CAN_H
+#define __INCLUDE_NUTTX_NET_CAN_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/can.h>
+#include <stdint.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define CAN_HDRLEN 4 //FIXME standard id vs extended
+#define NET_CAN_PKTSIZE sizeof(struct canfd_frame) // max size we can send through socket
+//FIXME think about can & canfd support
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __INCLUDE_NUTTX_NET_CAN_H */
diff --git a/include/nuttx/net/net.h b/include/nuttx/net/net.h
index 8218c0c..8c11db7 100644
--- a/include/nuttx/net/net.h
+++ b/include/nuttx/net/net.h
@@ -155,7 +155,8 @@ enum net_lltype_e
   NET_LL_BLUETOOTH,    /* Bluetooth */
   NET_LL_IEEE80211,    /* IEEE 802.11 */
   NET_LL_IEEE802154,   /* IEEE 802.15.4 MAC */
-  NET_LL_PKTRADIO      /* Non-standard packet radio */
+  NET_LL_PKTRADIO,     /* Non-standard packet radio */
+  NET_LL_CAN           /* CAN bus */
 };
 
 /* This defines a bitmap big enough for one bit for each socket option */
diff --git a/net/can/Make.defs b/net/can/Make.defs
index bb9ef9f..f8488c0 100644
--- a/net/can/Make.defs
+++ b/net/can/Make.defs
@@ -22,8 +22,14 @@
 
 ifeq ($(CONFIG_NET_CAN),y)
 
+# Socket layer
+
 SOCK_CSRCS += can_sockif.c
+SOCK_CSRCS += can_send.c
+
 NET_CSRCS += can_conn.c
+NET_CSRCS += can_poll.c
+NET_CSRCS += can_callback.c
 
 # Include can build support
 
diff --git a/net/can/can.h b/net/can/can.h
index 6f41ce9..3fed49b 100644
--- a/net/can/can.h
+++ b/net/can/can.h
@@ -32,6 +32,7 @@
 
 #include <netpacket/can.h>
 #include <nuttx/semaphore.h>
+#include <nuttx/net/netdev.h>
 
 #include "devif/devif.h"
 #include "socket/socket.h"
@@ -39,6 +40,17 @@
 #ifdef CONFIG_NET_CAN
 
 /****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Allocate a new packet socket data callback */
+
+#define can_callback_alloc(dev,conn) \
+  devif_callback_alloc(dev, &conn->list)
+#define can_callback_free(dev,conn,cb) \
+  devif_conn_callback_free(dev, cb, &conn->list)
+
+/****************************************************************************
  * Public Type Definitions
  ****************************************************************************/
 
@@ -57,6 +69,8 @@ struct can_conn_s
 
   FAR struct devif_callback_s *list; /* NetLink callbacks */
 
+  FAR struct net_driver_s *dev;      /* Reference to CAN device */
+
   /* CAN-specific content follows */
 
   uint8_t protocol;                  /* Selected CAN protocol */
@@ -135,6 +149,43 @@ void can_free(FAR struct can_conn_s *conn);
 FAR struct can_conn_s *can_nextconn(FAR struct can_conn_s *conn);
 
 /****************************************************************************
+ * Name: can_callback
+ *
+ * Description:
+ *   Inform the application holding the packet socket of a change in state.
+ *
+ * Returned Value:
+ *   OK if packet has been processed, otherwise ERROR.
+ *
+ * Assumptions:
+ *   This function is called from network logic at with the network locked.
+ *
+ ****************************************************************************/
+
+uint16_t can_callback(FAR struct net_driver_s *dev,
+                      FAR struct can_conn_s *conn, uint16_t flags);
+
+/****************************************************************************
+ * Name: can_poll
+ *
+ * Description:
+ *   Poll a CAN connection structure for availability of TX data
+ *
+ * Input Parameters:
+ *   dev - The device driver structure to use in the send operation
+ *   conn - The CAN "connection" to poll for TX data
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *   Called from network stack logic with the network stack locked
+ *
+ ****************************************************************************/
+
+void can_poll(FAR struct net_driver_s *dev, FAR struct can_conn_s *conn);
+
+/****************************************************************************
  * Name: can_active()
  *
  * Description:
@@ -145,6 +196,30 @@ FAR struct can_conn_s *can_nextconn(FAR struct can_conn_s *conn);
 
 FAR struct can_conn_s *can_active(FAR struct sockaddr_can *addr);
 
+/****************************************************************************
+ * Name: psock_can_send
+ *
+ * Description:
+ *   The psock_can_send() call may be used only when the packet socket is in
+ *   a connected state (so that the intended recipient is known).
+ *
+ * Input Parameters:
+ *   psock    An instance of the internal socket structure.
+ *   buf      Data to send
+ *   len      Length of data to send
+ *
+ * Returned Value:
+ *   On success, returns the number of characters sent.  On  error,
+ *   a negated errno value is returned.  See send() for the complete list
+ *   of return values.
+ *
+ ****************************************************************************/
+
+struct socket;
+ssize_t psock_can_send(FAR struct socket *psock, FAR const void *buf,
+                       size_t len);
+
+
 #undef EXTERN
 #ifdef __cplusplus
 }
diff --git a/net/devif/devif_pktsend.c b/net/can/can_callback.c
similarity index 53%
copy from net/devif/devif_pktsend.c
copy to net/can/can_callback.c
index b041b2f..2fad951 100644
--- a/net/devif/devif_pktsend.c
+++ b/net/can/can_callback.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * net/devif/devif_pktsend.c
+ * net/pkt/pkt_callback.c
  *
  *   Copyright (C) 2014 Gregory Nutt. All rights reserved.
  *   Author: Gregory Nutt <gn...@nuttx.org>
@@ -38,76 +38,48 @@
  ****************************************************************************/
 
 #include <nuttx/config.h>
+#if defined(CONFIG_NET) && defined(CONFIG_NET_CAN)
 
-#include <string.h>
-#include <assert.h>
+#include <stdint.h>
 #include <debug.h>
 
+#include <nuttx/net/netconfig.h>
 #include <nuttx/net/netdev.h>
 
-#ifdef CONFIG_NET_PKT
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Private Type Declarations
- ****************************************************************************/
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-/****************************************************************************
- * Public Constant Data
- ****************************************************************************/
-
-/****************************************************************************
- * Public Data
- ****************************************************************************/
-
-/****************************************************************************
- * Private Constant Data
- ****************************************************************************/
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
+#include "devif/devif.h"
+#include "can/can.h"
 
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
 
 /****************************************************************************
- * Name: devif_pkt_send
+ * Name: can_callback
  *
  * Description:
- *   Called from socket logic in order to send a raw packet in response to
- *   an xmit or poll request from the network interface driver.
+ *   Inform the application holding the packet socket of a change in state.
  *
- *   This is almost identical to calling devif_send() except that the data to
- *   be sent is copied into dev->d_buf (vs. dev->d_appdata), since there is
- *   no header on the data.
+ * Returned Value:
+ *   OK if packet has been processed, otherwise ERROR.
  *
  * Assumptions:
- *   Called with the network locked.
+ *   This function is called with the network locked.
  *
  ****************************************************************************/
 
-void devif_pkt_send(FAR struct net_driver_s *dev, FAR const void *buf,
-                    unsigned int len)
+uint16_t can_callback(FAR struct net_driver_s *dev,
+                      FAR struct can_conn_s *conn, uint16_t flags)
 {
-  DEBUGASSERT(dev && len > 0 && len < NETDEV_PKTSIZE(dev));
-
-  /* Copy the data into the device packet buffer */
+  /* Some sanity checking */
 
-  memcpy(dev->d_buf, buf, len);
+  if (conn)
+    {
+      /* Perform the callback */
 
-  /* Set the number of bytes to send */
+      flags = devif_conn_event(dev, conn, flags, conn->list);
+    }
 
-  dev->d_len    = len;
-  dev->d_sndlen = len;
+  return flags;
 }
 
-#endif /* CONFIG_NET_PKT */
+#endif /* CONFIG_NET && CONFIG_NET_CAN */
diff --git a/net/can/can_poll.c b/net/can/can_poll.c
new file mode 100644
index 0000000..84aeeab
--- /dev/null
+++ b/net/can/can_poll.c
@@ -0,0 +1,107 @@
+/****************************************************************************
+ * net/pkt/pkt_poll.c
+ * Poll for the availability of packet TX data
+ *
+ *   Copyright (C) 2014 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <gn...@nuttx.org>
+ *
+ * Adapted for NuttX from logic in uIP which also has a BSD-like license:
+ *
+ *   Original author Adam Dunkels <ad...@dunkels.com>
+ *   Copyright () 2001-2003, Adam Dunkels.
+ *   All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#if defined(CONFIG_NET) && defined(CONFIG_NET_CAN)
+
+#include <debug.h>
+
+#include <nuttx/net/netconfig.h>
+#include <nuttx/net/netdev.h>
+
+#include "devif/devif.h"
+#include "can/can.h"
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: can_poll
+ *
+ * Description:
+ *   Poll a packet "connection" structure for availability of TX data
+ *
+ * Input Parameters:
+ *   dev - The device driver structure to use in the send operation
+ *   conn - The packet "connection" to poll for TX data
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *   The network is locked.
+ *
+ ****************************************************************************/
+
+void can_poll(FAR struct net_driver_s *dev, FAR struct can_conn_s *conn)
+{
+  /* Verify that the packet connection is valid */
+
+  if (conn != NULL)
+    {
+      /* Setup for the application callback */
+
+      dev->d_appdata = &dev->d_buf[NET_LL_HDRLEN(dev)];
+      dev->d_len     = 0;
+      dev->d_sndlen  = 0;
+
+      /* Perform the application callback */
+
+      can_callback(dev, conn, CAN_POLL);
+
+      /* Check if the application has data to send */
+
+      if (dev->d_sndlen > 0)
+        {
+          return;
+        }
+    }
+
+  /* Make sure that d_len is zero meaning that there is nothing to be sent */
+
+  dev->d_len = 0;
+}
+
+#endif /* CONFIG_NET && CONFIG_NET_CAN */
diff --git a/net/can/can_send.c b/net/can/can_send.c
new file mode 100644
index 0000000..6b7a609
--- /dev/null
+++ b/net/can/can_send.c
@@ -0,0 +1,264 @@
+/****************************************************************************
+ * net/can/can_send.c
+ *
+ *   Copyright (C) 2014, 2016-2017 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <gn...@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#if defined(CONFIG_NET) && defined(CONFIG_NET_CAN)
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <arch/irq.h>
+
+#include <nuttx/semaphore.h>
+#include <nuttx/net/netdev.h>
+#include <nuttx/net/net.h>
+#include <nuttx/net/ip.h>
+
+#include "netdev/netdev.h"
+#include "devif/devif.h"
+#include "socket/socket.h"
+#include "can/can.h"
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* This structure holds the state of the send operation until it can be
+ * operated upon by the event handler.
+ */
+
+struct send_s
+{
+  FAR struct socket      *snd_sock;    /* Points to the parent socket structure */
+  FAR struct devif_callback_s *snd_cb; /* Reference to callback instance */
+  sem_t                   snd_sem;     /* Used to wake up the waiting thread */
+  FAR const uint8_t      *snd_buffer;  /* Points to the buffer of data to send */
+  size_t                  snd_buflen;  /* Number of bytes in the buffer to send */
+  ssize_t                 snd_sent;    /* The number of bytes sent */
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: psock_send_eventhandler
+ ****************************************************************************/
+
+static uint16_t psock_send_eventhandler(FAR struct net_driver_s *dev,
+                                        FAR void *pvconn,
+                                        FAR void *pvpriv, uint16_t flags)
+{
+  FAR struct send_s *pstate = (FAR struct send_s *)pvpriv;
+
+  if (pstate)
+    {
+      /* Check if the outgoing packet is available. It may have been claimed
+       * by a send event handler serving a different thread -OR- if the
+       * output buffer currently contains unprocessed incoming data. In
+       * these cases we will just have to wait for the next polling cycle.
+       */
+
+      if (dev->d_sndlen > 0 || (flags & CAN_NEWDATA) != 0)
+        {
+          /* Another thread has beat us sending data or the buffer is busy,
+           * Check for a timeout. If not timed out, wait for the next
+           * polling cycle and check again.
+           */
+
+          /* No timeout. Just wait for the next polling cycle */
+
+          return flags;
+        }
+
+      /* It looks like we are good to send the data */
+
+      else
+        {
+          /* Copy the packet data into the device packet buffer and send it */
+          //FIXME potentialy wrong function do we have a header??
+    	  devif_pkt_send(dev, pstate->snd_buffer, pstate->snd_buflen);
+          pstate->snd_sent = pstate->snd_buflen;
+        }
+
+      /* Don't allow any further call backs. */
+
+      pstate->snd_cb->flags    = 0;
+      pstate->snd_cb->priv     = NULL;
+      pstate->snd_cb->event    = NULL;
+
+      /* Wake up the waiting thread */
+
+      nxsem_post(&pstate->snd_sem);
+    }
+
+  return flags;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: psock_can_send
+ *
+ * Description:
+ *   The psock_can_send() call may be used only when the packet socket is in
+ *   a connected state (so that the intended recipient is known).
+ *
+ * Input Parameters:
+ *   psock    An instance of the internal socket structure.
+ *   buf      Data to send
+ *   len      Length of data to send
+ *
+ * Returned Value:
+ *   On success, returns the number of characters sent.  On  error,
+ *   a negated errno value is retruend.  See send() for the complete list
+ *   of return values.
+ *
+ ****************************************************************************/
+
+ssize_t psock_can_send(FAR struct socket *psock, FAR const void *buf,
+                       size_t len)
+{
+  FAR struct net_driver_s *dev;
+  FAR struct can_conn_s *conn; 
+  struct send_s state;
+  int ret = OK;
+  
+  conn = (FAR struct can_conn_s *)psock->s_conn;
+
+  /* Verify that the sockfd corresponds to valid, allocated socket */
+
+  if (!psock || psock->s_crefs <= 0)
+    {
+      return -EBADF;
+    }
+
+  /* Get the device driver that will service this transfer */
+
+  dev = conn->dev;
+  if (dev == NULL)
+    {
+      return -ENODEV;
+    }
+
+  /* Perform the send operation */
+
+  /* Initialize the state structure. This is done with the network locked
+   * because we don't want anything to happen until we are ready.
+   */
+
+  net_lock();
+  memset(&state, 0, sizeof(struct send_s));
+
+  /* This semaphore is used for signaling and, hence, should not have
+   * priority inheritance enabled.
+   */
+
+  nxsem_init(&state.snd_sem, 0, 0); /* Doesn't really fail */
+  nxsem_setprotocol(&state.snd_sem, SEM_PRIO_NONE);
+
+  state.snd_sock      = psock;          /* Socket descriptor to use */
+  state.snd_buflen    = len;            /* Number of bytes to send */
+  state.snd_buffer    = buf;            /* Buffer to send from */
+
+  if (len > 0)
+    {
+      /* Allocate resource to receive a callback */
+
+      state.snd_cb = can_callback_alloc(dev, conn);
+      if (state.snd_cb)
+        {
+          /* Set up the callback in the connection */
+
+          state.snd_cb->flags = CAN_POLL;
+          state.snd_cb->priv  = (FAR void *)&state;
+          state.snd_cb->event = psock_send_eventhandler;
+
+          /* Notify the device driver that new TX data is available. */
+
+          netdev_txnotify_dev(dev);
+
+          /* Wait for the send to complete or an error to occur.
+           * net_lockedwait will also terminate if a signal is received.
+           */
+
+          ret = net_lockedwait(&state.snd_sem);
+
+          /* Make sure that no further events are processed */
+
+          can_callback_free(dev, conn, state.snd_cb);
+        }
+    }
+
+  nxsem_destroy(&state.snd_sem);
+  net_unlock();
+
+  /* Check for a errors, Errors are signalled by negative errno values
+   * for the send length
+   */
+
+  if (state.snd_sent < 0)
+    {
+      return state.snd_sent;
+    }
+
+  /* If net_lockedwait failed, then we were probably reawakened by a signal.
+   * In this case, net_lockedwait will have returned negated errno
+   * appropriately.
+   */
+
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  /* Return the number of bytes actually sent */
+
+  return state.snd_sent;
+}
+
+#endif /* CONFIG_NET && CONFIG_NET_CAN */
diff --git a/net/can/can_sockif.c b/net/can/can_sockif.c
index b7e3fe6..1de95d9 100644
--- a/net/can/can_sockif.c
+++ b/net/can/can_sockif.c
@@ -40,6 +40,7 @@
 #include <nuttx/net/net.h>
 
 #include "can/can.h"
+#include "netdev/netdev.h"
 
 #ifdef CONFIG_NET_CAN
 
@@ -61,7 +62,7 @@ static int  can_connect(FAR struct socket *psock,
               FAR const struct sockaddr *addr, socklen_t addrlen);
 static int  can_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
               FAR socklen_t *addrlen, FAR struct socket *newsock);
-static int  can_poll(FAR struct socket *psock, FAR struct pollfd *fds,
+static int  can_poll_local(FAR struct socket *psock, FAR struct pollfd *fds,
               bool setup);
 static ssize_t can_send(FAR struct socket *psock,
               FAR const void *buf, size_t len, int flags);
@@ -88,7 +89,7 @@ const struct sock_intf_s g_can_sockif =
   can_listen,       /* si_listen */
   can_connect,      /* si_connect */
   can_accept,       /* si_accept */
-  can_poll,         /* si_poll */
+  can_poll_local,         /* si_poll */
   can_send,         /* si_send */
   can_sendto,       /* si_sendto */
 #ifdef CONFIG_NET_SENDFILE
@@ -272,7 +273,15 @@ static int can_bind(FAR struct socket *psock,
 
   canaddr         = (FAR struct sockaddr_can *)addr;
   conn            = (FAR struct can_conn_s *)psock->s_conn;
-#warning Missing logic
+
+  /* Bind CAN device to socket */
+
+  //TODO better support for CONFIG_NETDEV_IFINDEX
+  char netdev_name[6];
+
+  sprintf(netdev_name, "can%i", canaddr->can_ifindex);
+
+  conn->dev = netdev_findbyname(&netdev_name);
 
   return OK;
 }
@@ -473,7 +482,7 @@ static int can_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
 }
 
 /****************************************************************************
- * Name: can_poll
+ * Name: can_poll_local
  *
  * Description:
  *   The standard poll() operation redirects operations on socket descriptors
@@ -495,7 +504,7 @@ static int can_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
  *
  ****************************************************************************/
 
-static int can_poll(FAR struct socket *psock, FAR struct pollfd *fds,
+static int can_poll_local(FAR struct socket *psock, FAR struct pollfd *fds,
                         bool setup)
 {
   FAR struct can_conn_s *conn;
@@ -621,36 +630,25 @@ static int can_poll(FAR struct socket *psock, FAR struct pollfd *fds,
 static ssize_t can_send(FAR struct socket *psock, FAR const void *buf,
                             size_t len, int flags)
 {
-  DEBUGASSERT(psock != NULL && psock->s_conn != NULL && buf != NULL);
-
-  /* The socket must be connected in order to use send */
-
-  if (_SS_ISBOUND(psock->s_flags))
-    {
-      FAR struct can_conn_s *conn;
-      struct sockaddr_can canaddr;
-
-      /* Get the underlying connection structure */
+	  ssize_t ret;
 
-      conn               = (FAR struct can_conn_s *)psock->s_conn;
+	  /* Only SOCK_RAW is supported */
 
-      /* Format the address */
-
-      canaddr.can_family = AF_CAN;
-#warning Missing logic
+	  if (psock->s_type == SOCK_RAW)
+	    {
+	      /* Raw packet send */
+	      ret = psock_can_send(psock, buf, len);
+	    }
+	  else
+	    {
+	      /* EDESTADDRREQ.  Signifies that the socket is not connection-mode and
+	       * no peer address is set.
+	       */
 
-      /* Then let sendto() perform the actual send operation */
-
-      return can_sendto(psock, buf, len, flags,
-                            (FAR const struct sockaddr *)&canaddr,
-                            sizeof(struct sockaddr_can));
-    }
-
-  /* EDESTADDRREQ.  Signifies that the socket is not connection-mode and no
-   * peer address is set.
-   */
+	      ret = -EDESTADDRREQ;
+	    }
 
-  return -EDESTADDRREQ;
+	  return ret;
 }
 
 /****************************************************************************
@@ -681,25 +679,8 @@ static ssize_t can_sendto(FAR struct socket *psock, FAR const void *buf,
                               size_t len, int flags,
                               FAR const struct sockaddr *to, socklen_t tolen)
 {
-  FAR struct can_conn_s *conn;
-  int ret;
-
-  DEBUGASSERT(psock != NULL && psock->s_conn != NULL && buf != NULL &&
-              to != NULL && tolen >= sizeof(struct sockaddr_can));
-
-  conn = (FAR struct can_conn_s *)psock->s_conn;
-#warning Missing logic
-
-  switch (conn->protocol)
-    {
-#warning Missing logic
-
-      default:
-       ret = -EOPNOTSUPP;
-       break;
-    }
-
-  return ret;
+   nerr("ERROR: sendto() not supported for raw packet sockets\n");
+   return -EAFNOSUPPORT;
 }
 
 /****************************************************************************
diff --git a/net/devif/Make.defs b/net/devif/Make.defs
index 714a0ce..b2dca4a 100644
--- a/net/devif/Make.defs
+++ b/net/devif/Make.defs
@@ -62,7 +62,7 @@ endif
 
 # Raw packet socket support
 
-ifeq ($(CONFIG_NET_PKT),y)
+ifeq ($(filter y,$(CONFIG_NET_PKT) $(CONFIG_NET_CAN)),)
 NET_CSRCS += devif_pktsend.c
 endif
 
diff --git a/net/devif/devif.h b/net/devif/devif.h
index cbe1a00..c54a68d 100644
--- a/net/devif/devif.h
+++ b/net/devif/devif.h
@@ -168,6 +168,7 @@
 #define BLUETOOTH_NEWDATA  TCP_NEWDATA
 #define IEEE802154_NEWDATA TCP_NEWDATA
 #define PKT_NEWDATA        TCP_NEWDATA
+#define CAN_NEWDATA        TCP_NEWDATA
 #define WPAN_NEWDATA       TCP_NEWDATA
 #define IPFWD_NEWDATA      TCP_NEWDATA
 #define TCP_SNDACK         (1 << 2)
@@ -175,6 +176,7 @@
 #define TCP_POLL           (1 << 4)
 #define UDP_POLL           TCP_POLL
 #define PKT_POLL           TCP_POLL
+#define CAN_POLL           TCP_POLL
 #define BLUETOOTH_POLL     TCP_POLL
 #define IEEE802154_POLL    TCP_POLL
 #define WPAN_POLL          TCP_POLL
@@ -492,7 +494,7 @@ void devif_iob_send(FAR struct net_driver_s *dev, FAR struct iob_s *buf,
  *
  ****************************************************************************/
 
-#ifdef CONFIG_NET_PKT
+#if defined(CONFIG_NET_PKT) || defined(CONFIG_NET_CAN)
 void devif_pkt_send(FAR struct net_driver_s *dev, FAR const void *buf,
                     unsigned int len);
 #endif
diff --git a/net/devif/devif_pktsend.c b/net/devif/devif_pktsend.c
index b041b2f..a5d0515 100644
--- a/net/devif/devif_pktsend.c
+++ b/net/devif/devif_pktsend.c
@@ -45,7 +45,7 @@
 
 #include <nuttx/net/netdev.h>
 
-#ifdef CONFIG_NET_PKT
+#if defined(CONFIG_NET_PKT) || defined(CONFIG_NET_CAN)
 
 /****************************************************************************
  * Pre-processor Definitions
diff --git a/net/devif/devif_poll.c b/net/devif/devif_poll.c
index 7c4fd04..e997a6f 100644
--- a/net/devif/devif_poll.c
+++ b/net/devif/devif_poll.c
@@ -50,6 +50,7 @@
 
 #include "devif/devif.h"
 #include "arp/arp.h"
+#include "can/can.h"
 #include "tcp/tcp.h"
 #include "udp/udp.h"
 #include "pkt/pkt.h"
@@ -233,6 +234,46 @@ static int devif_poll_pkt_connections(FAR struct net_driver_s *dev,
 #endif /* CONFIG_NET_PKT */
 
 /****************************************************************************
+ * Name: devif_poll_pkt_connections
+ *
+ * Description:
+ *   Poll all packet connections for available packets to send.
+ *
+ * Assumptions:
+ *   This function is called from the MAC device driver with the network
+ *   locked.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_CAN
+static int devif_poll_can_connections(FAR struct net_driver_s *dev,
+                                      devif_poll_callback_t callback)
+{
+  FAR struct can_conn_s *can_conn = NULL;
+  int bstop = 0;
+
+  /* Traverse all of the allocated packet connections and perform the poll action */
+
+  while (!bstop && (can_conn = can_nextconn(can_conn)))
+    {
+      /* Perform the packet TX poll */
+
+      can_poll(dev, can_conn);
+
+      /* Perform any necessary conversions on outgoing packets */
+
+      devif_packet_conversion(dev, DEVIF_CAN);
+
+      /* Call back into the driver */
+
+      bstop = callback(dev);
+    }
+
+  return bstop;
+}
+#endif /* CONFIG_NET_PKT */
+
+/****************************************************************************
  * Name: devif_poll_bluetooth_connections
  *
  * Description:
@@ -646,6 +687,14 @@ int devif_poll(FAR struct net_driver_s *dev, devif_poll_callback_t callback)
 
   if (!bstop)
 #endif
+#ifdef CONFIG_NET_CAN
+    {
+      /* Check for pending packet socket transfer */
+      bstop = devif_poll_can_connections(dev, callback);
+    }
+
+  if (!bstop)
+#endif
 #ifdef CONFIG_NET_BLUETOOTH
     {
       /* Check for pending PF_BLUETOOTH socket transfer */
diff --git a/net/local/local_sendpacket.c b/net/local/local_sendpacket.c
index 68dfac6..644dd31 100644
--- a/net/local/local_sendpacket.c
+++ b/net/local/local_sendpacket.c
@@ -47,6 +47,7 @@
 #include <debug.h>
 
 #include <nuttx/fs/fs.h>
+#include "devif/devif.h"
 
 #include "local/local.h"
 
diff --git a/net/netdev/netdev_register.c b/net/netdev/netdev_register.c
index 85483dc..fc4634b 100644
--- a/net/netdev/netdev_register.c
+++ b/net/netdev/netdev_register.c
@@ -37,6 +37,7 @@
 #include <nuttx/net/netdev.h>
 #include <nuttx/net/ethernet.h>
 #include <nuttx/net/bluetooth.h>
+#include <nuttx/net/can.h>
 
 #include "utils/utils.h"
 #include "igmp/igmp.h"
@@ -55,6 +56,7 @@
 #define NETDEV_PAN_FORMAT   "pan%d"
 #define NETDEV_WLAN_FORMAT  "wlan%d"
 #define NETDEV_WPAN_FORMAT  "wpan%d"
+#define NETDEV_CAN_FORMAT   "can%d"
 
 #if defined(CONFIG_DRIVERS_IEEE80211) /* Usually also has CONFIG_NET_ETHERNET */
 #  define NETDEV_DEFAULT_FORMAT NETDEV_WLAN_FORMAT
@@ -66,6 +68,8 @@
 #  define NETDEV_DEFAULT_FORMAT NETDEV_SLIP_FORMAT
 #elif defined(CONFIG_NET_TUN)
 #  define NETDEV_DEFAULT_FORMAT NETDEV_TUN_FORMAT
+#elif defined(CONFIG_NET_CAN)
+#  define NETDEV_DEFAULT_FORMAT NETDEV_CAN_FORMAT
 #else /* if defined(CONFIG_NET_LOOPBACK) */
 #  define NETDEV_DEFAULT_FORMAT NETDEV_LO_FORMAT
 #endif
@@ -276,6 +280,14 @@ int netdev_register(FAR struct net_driver_s *dev, enum net_lltype_e lltype)
             break;
 #endif
 
+#ifdef CONFIG_NET_CAN
+          case NET_LL_CAN:  /* CAN bus */
+            dev->d_llhdrlen = 0;
+            dev->d_pktsize  = NET_CAN_PKTSIZE;
+            devfmt          = NETDEV_CAN_FORMAT;
+            break;
+#endif
+
 #ifdef CONFIG_NET_BLUETOOTH
           case NET_LL_BLUETOOTH:              /* Bluetooth */
             llhdrlen = BLUETOOTH_MAX_HDRLEN;  /* Determined at runtime */


[incubator-nuttx] 05/31: Added GPIO code to test SocketCAN performance

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch SocketCAN
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 99952a3d7206c96d4d355f2a18d7cecd5e3df681
Author: Peter van der Perk <pe...@nxp.com>
AuthorDate: Wed Feb 19 17:46:37 2020 +0100

    Added GPIO code to test SocketCAN performance
---
 arch/arm/src/s32k1xx/s32k1xx_flexcan.c | 94 ++++++++++++++++------------------
 1 file changed, 43 insertions(+), 51 deletions(-)

diff --git a/arch/arm/src/s32k1xx/s32k1xx_flexcan.c b/arch/arm/src/s32k1xx/s32k1xx_flexcan.c
index 74a21b8..7046050 100644
--- a/arch/arm/src/s32k1xx/s32k1xx_flexcan.c
+++ b/arch/arm/src/s32k1xx/s32k1xx_flexcan.c
@@ -115,20 +115,19 @@
 #  error "Need at least one RX buffer"
 #endif*/
 
-#define S32K1XX_FLEXCAN_FIRST_TX_MB 10
-
 #define MaskStdID                   0x000007FF;
 #define MaskExtID                   0x1FFFFFFF;
 
 //Fixme nice variables/constants
-#define NumMBinFiFoAndFilters       10 //FIXME
-#define NumTxMesgBuffers            6
-#define HWMaxMB                     16
-#define TXMBMask                    (0b111111 << NumMBinFiFoAndFilters)
+#define RxMBCount                   10
+#define TxMBCount                   6
+#define TotalMBcount                RxMBCount + TxMBCount
+#define TXMBMask                    (((1 << TxMBCount)-1) << RxMBCount)
 
 #define CAN_FIFO_NE                 (1 << 5)
 #define CAN_FIFO_OV                 (1 << 6)
 #define CAN_FIFO_WARN               (1 << 7)
+#define FIFO_IFLAG1                 CAN_FIFO_NE | CAN_FIFO_WARN | CAN_FIFO_OV
 
 static int peak_tx_mailbox_index_ = 0;
 
@@ -449,12 +448,12 @@ static int s32k1xx_transmit(FAR struct s32k1xx_driver_s *priv)
 
   struct can_frame *frame = (struct can_frame*)priv->dev.d_buf;
 
-  /*printf("CAN id: %i dlc: %i", frame->can_id, frame->can_dlc);
+  /*ninfo("CAN id: %i dlc: %i", frame->can_id, frame->can_dlc);
 
   for(int i = 0; i < frame->can_dlc; i++){
-	  printf(" %02X", frame->data[i]);
+	  ninfo(" %02X", frame->data[i]);
   }
-  printf("\r\n");*/
+  ninfo("\r\n");*/
 
   /* Attempt to write frame */
   uint32_t mbi = 0;
@@ -463,9 +462,9 @@ static int s32k1xx_transmit(FAR struct s32k1xx_driver_s *priv)
 	  mbi = (getreg32(S32K1XX_CAN0_ESR2) & CAN_ESR2_LPTM_MASK) >> CAN_ESR2_LPTM_SHIFT;
   }
 
-  uint32_t mb_bit = 1 << (NumMBinFiFoAndFilters + mbi);
+  uint32_t mb_bit = 1 << (RxMBCount + mbi);
 
-  while (mbi < NumTxMesgBuffers)
+  while (mbi < TxMBCount)
   {
 
 	  if (priv->tx[mbi].CS.code != CAN_TXMB_DATAORREMOTE)
@@ -477,7 +476,7 @@ static int s32k1xx_transmit(FAR struct s32k1xx_driver_s *priv)
 	  mbi++;
   }
 
-  if (mbi == NumTxMesgBuffers)
+  if (mbi == TxMBCount)
   {
 	  return 0;       // No transmission for you!
   }
@@ -502,7 +501,8 @@ static int s32k1xx_transmit(FAR struct s32k1xx_driver_s *priv)
   //cs.rtr = frame.isRemoteTransmissionRequest();
 
   cs.dlc = frame->can_dlc;
-  //FIXME endian swap instruction or somekind
+
+  //FIXME endian swap instruction or somekind takes 1.5us right now
   mb->data.b0 = frame->data[0];
   mb->data.b1 = frame->data[1];
   mb->data.b2 = frame->data[2];
@@ -522,6 +522,9 @@ static int s32k1xx_transmit(FAR struct s32k1xx_driver_s *priv)
   txi.abort_on_error = (flags & uavcan::CanIOFlagAbortOnError) != 0;
   txi.pending        = TxItem::busy;*/
 
+
+  s32k1xx_gpiowrite(PIN_PORTD | PIN31, 0);
+
   mb->CS = cs; // Go.
 
   uint32_t regval;
@@ -641,7 +644,7 @@ static inline void s32k1xx_dispatch(FAR struct s32k1xx_driver_s *priv)
 static void s32k1xx_receive(FAR struct s32k1xx_driver_s *priv)
 {
   #warning Missing logic
-	printf("FLEXCAN: receive\r\n");
+	ninfo("FLEXCAN: receive\r\n");
 }
 
 /****************************************************************************
@@ -673,14 +676,14 @@ static void s32k1xx_txdone(FAR struct s32k1xx_driver_s *priv)
 
   /* Process TX completions */
 
-  uint32_t mb_bit = 1 << NumMBinFiFoAndFilters;
-  for(uint32_t mbi = 0; tx_iflags && mbi < NumTxMesgBuffers; mbi++)
+  uint32_t mb_bit = 1 << RxMBCount;
+  for(uint32_t mbi = 0; tx_iflags && mbi < TxMBCount; mbi++)
   {
       if (tx_iflags & mb_bit)
       {
     	  putreg32(mb_bit, S32K1XX_CAN0_IFLAG1);
           tx_iflags &= ~mb_bit;
-          const bool txok = priv->tx[mbi].CS.code != CAN_TXMB_ABORT;
+          //const bool txok = priv->tx[mbi].CS.code != CAN_TXMB_ABORT;
           //handleTxMailboxInterrupt(mbi, txok, utc_usec);
       }
       mb_bit <<= 1;
@@ -734,8 +737,9 @@ static int s32k1xx_flexcan_interrupt(int irq, FAR void *context, FAR void *arg)
 {
   #warning Missing logic
 
+	ninfo("FLEXCAN INT %i\r\n", irq);
+
 	FAR struct s32k1xx_driver_s *priv = &g_flexcan[0];
-	uint32_t FIFO_IFLAG1 = CAN_FIFO_NE | CAN_FIFO_WARN | CAN_FIFO_OV;
 	uint32_t flags;
 	flags  = getreg32(S32K1XX_CAN0_IFLAG1);
 	flags &= FIFO_IFLAG1;
@@ -773,7 +777,7 @@ static int s32k1xx_flexcan_interrupt(int irq, FAR void *context, FAR void *arg)
 static void s32k1xx_txtimeout_work(FAR void *arg)
 {
   #warning Missing logic
-	  printf("FLEXCAN: tx timeout work\r\n");
+	  ninfo("FLEXCAN: tx timeout work\r\n");
 }
 
 /****************************************************************************
@@ -798,7 +802,7 @@ static void s32k1xx_txtimeout_work(FAR void *arg)
 static void s32k1xx_txtimeout_expiry(int argc, uint32_t arg, ...)
 {
   #warning Missing logic
-	  printf("FLEXCAN: tx timeout expiry\r\n");
+	  ninfo("FLEXCAN: tx timeout expiry\r\n");
 }
 
 /****************************************************************************
@@ -821,7 +825,7 @@ static void s32k1xx_txtimeout_expiry(int argc, uint32_t arg, ...)
 static void s32k1xx_poll_work(FAR void *arg)
 {
   #warning Missing logic
-	  //printf("FLEXCAN: poll work\r\n");
+	  //ninfo("FLEXCAN: poll work\r\n");
 
 	  FAR struct s32k1xx_driver_s *priv = (FAR struct s32k1xx_driver_s *)arg;
 
@@ -941,11 +945,14 @@ static int s32k1xx_ifup(struct net_driver_s *dev)
   uint32_t regval;
 
   #warning Missing logic
-  printf("FLEXCAN: test ifup\r\n");
+  ninfo("FLEXCAN: test ifup\r\n");
 
   /* initialize CAN device */
   //FIXME we only support a single can device for now
 
+  //TEST GPIO tming
+  s32k1xx_pinconfig(PIN_PORTD | PIN31 | GPIO_OUTPUT);
+
 
   regval  = getreg32(S32K1XX_CAN0_MCR);
   regval |= CAN_MCR_MDIS;
@@ -964,7 +971,7 @@ static int s32k1xx_ifup(struct net_driver_s *dev)
   regval  = getreg32(S32K1XX_CAN0_MCR);
   regval |= CAN_MCR_RFEN | CAN_MCR_SLFWAK | CAN_MCR_WRNEN | CAN_MCR_SRXDIS
 		  | CAN_MCR_IRMQ | CAN_MCR_AEN |
-		  (((HWMaxMB - 1) << CAN_MCR_MAXMB_SHIFT) & CAN_MCR_MAXMB_MASK);
+		  (((TotalMBcount - 1) << CAN_MCR_MAXMB_SHIFT) & CAN_MCR_MAXMB_MASK);
   putreg32(regval, S32K1XX_CAN0_MCR);
 
   regval  = CAN_CTRL2_RRS | CAN_CTRL2_EACEN | CAN_CTRL2_RFFN_16MB; //FIXME TASD
@@ -974,7 +981,7 @@ static int s32k1xx_ifup(struct net_driver_s *dev)
   s32k1xx_setfreeze(1);
   if(!s32k1xx_waitfreezeack_change(1))
   {
-	  printf("FLEXCAN: freeze fail\r\n");
+	  ninfo("FLEXCAN: freeze fail\r\n");
 	  return -1;
   }
 
@@ -1035,50 +1042,35 @@ static int s32k1xx_ifup(struct net_driver_s *dev)
 #endif
 
 
-  /* Filtering catchall */
-  putreg32(0, S32K1XX_CAN0_RXFGMASK);
 
   /* Iniatilize all MB rx and tx */
-  /*for(int i = 0; i < HWMaxMB; i++)
+  for(int i = 0; i < TotalMBcount; i++)
   {
+	  ninfo("MB %i %p\r\n", i, &priv->rx[i]);
+	  ninfo("MB %i %p\r\n", i, &priv->rx[i].ID.w);
 	  priv->rx[i].CS.cs = 0x0;
 	  priv->rx[i].ID.w = 0x0;
 	  priv->rx[i].data.l = 0x0;
 	  priv->rx[i].data.h = 0x0;
-  }*/
+  }
+
+  /* Filtering catchall */
+  putreg32(0x0, S32K1XX_CAN0_RXFGMASK);
 
-  //FIXME max mb
-  for(int i = 0; i < HWMaxMB; i++)
+  for(int i = 0; i < TotalMBcount; i++)
   {
 	  putreg32(0,S32K1XX_CAN0_RXIMR(i));
   }
 
-  putreg32(0,S32K1XX_CAN0_RXIMR0);
-  putreg32(0,S32K1XX_CAN0_RXIMR1);
-  putreg32(0,S32K1XX_CAN0_RXIMR2);
-  putreg32(0,S32K1XX_CAN0_RXIMR3);
-  putreg32(0,S32K1XX_CAN0_RXIMR4);
-  putreg32(0,S32K1XX_CAN0_RXIMR5);
-  putreg32(0,S32K1XX_CAN0_RXIMR6);
-  putreg32(0,S32K1XX_CAN0_RXIMR7);
-  putreg32(0,S32K1XX_CAN0_RXIMR8);
-  putreg32(0,S32K1XX_CAN0_RXIMR9);
-  putreg32(0,S32K1XX_CAN0_RXIMR10);
-  putreg32(0,S32K1XX_CAN0_RXIMR11);
-  putreg32(0,S32K1XX_CAN0_RXIMR12);
-  putreg32(0,S32K1XX_CAN0_RXIMR13);
-  putreg32(0,S32K1XX_CAN0_RXIMR14);
-  putreg32(0,S32K1XX_CAN0_RXIMR15);
-
-  putreg32(CAN_IFLAG1(1) | TXMBMask, S32K1XX_CAN0_IFLAG1); //FIXME dynamic MXMB
-  putreg32(CAN_IFLAG1(1), S32K1XX_CAN0_IMASK1);
+  putreg32(FIFO_IFLAG1 | TXMBMask, S32K1XX_CAN0_IFLAG1);
+  putreg32(FIFO_IFLAG1, S32K1XX_CAN0_IMASK1);
 
 
   /* Exit freeze mode */
   s32k1xx_setfreeze(0);
   if(!s32k1xx_waitfreezeack_change(0))
   {
-	  printf("FLEXCAN: unfreeze fail\r\n");
+	  ninfo("FLEXCAN: unfreeze fail\r\n");
 	  return -1;
   }
 
@@ -1381,7 +1373,7 @@ int s32k1xx_netinitialize(int intf)
   priv->txtimeout     = wd_create();      /* Create TX timeout timer */
   priv->rx            = (struct MbRx *)(S32K1XX_CAN0_MB);
   priv->tx            = (struct MbTx *)(S32K1XX_CAN0_MB + (sizeof(struct MbRx)
-		                                * S32K1XX_FLEXCAN_FIRST_TX_MB) );
+		                                * RxMBCount) );
 
   /* Put the interface in the down state.  This usually amounts to resetting
    * the device and/or calling s32k1xx_ifdown().


[incubator-nuttx] 31/31: Use LPO 32Khz clock for RTC

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch SocketCAN
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 2df19bfe4d50cfa6afbc95404b5180a70719c00c
Author: Peter van der Perk <pe...@nxp.com>
AuthorDate: Wed Mar 18 12:27:39 2020 +0100

    Use LPO 32Khz clock for RTC
---
 boards/arm/s32k1xx/s32k148evb/src/s32k1xx_clockconfig.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/boards/arm/s32k1xx/s32k148evb/src/s32k1xx_clockconfig.c b/boards/arm/s32k1xx/s32k148evb/src/s32k1xx_clockconfig.c
index d41060b..ac597ce 100644
--- a/boards/arm/s32k1xx/s32k148evb/src/s32k1xx_clockconfig.c
+++ b/boards/arm/s32k1xx/s32k148evb/src/s32k1xx_clockconfig.c
@@ -165,7 +165,7 @@ const struct clock_configuration_s g_initial_clkconfig =
     },
     .lpoclk        =                                   /* Low Power Clock configuration. */
     {
-      .rtc_source  = SIM_RTCCLK_SEL_SOSCDIV1_CLK,      /* RTCCLKSEL */
+      .rtc_source  = SIM_RTCCLK_SEL_LPO_32K,           /* RTCCLKSEL */
       .lpo_source  = SIM_LPO_CLK_SEL_LPO_128K,         /* LPOCLKSEL */
       .initialize  = true,                             /* Initialize */
       .lpo32k      = true,                             /* LPO32KCLKEN */


[incubator-nuttx] 01/31: include/sys/socket.h: Add CAN socket family.

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch SocketCAN
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit a371873ec6bd063da1a8ad2c70b74bfe73a62663
Author: Gregory Nutt <gn...@nuttx.org>
AuthorDate: Thu Feb 13 09:57:38 2020 -0600

    include/sys/socket.h:  Add CAN socket family.
---
 include/sys/socket.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/sys/socket.h b/include/sys/socket.h
index b940126..e85242e 100644
--- a/include/sys/socket.h
+++ b/include/sys/socket.h
@@ -62,6 +62,7 @@
 #define PF_NETLINK    16         /* Netlink IPC socket */
 #define PF_ROUTE      PF_NETLINK /* 4.4BSD Compatibility*/
 #define PF_PACKET     17         /* Low level packet interface */
+#define PF_CAN        29         /* Controller Area Network (SocketCAN) */
 #define PF_BLUETOOTH  31         /* Bluetooth sockets */
 #define PF_IEEE802154 36         /* Low level IEEE 802.15.4 radio frame interface */
 #define PF_PKTRADIO   64         /* Low level packet radio interface */
@@ -78,6 +79,7 @@
 #define AF_NETLINK     PF_NETLINK
 #define AF_ROUTE       PF_ROUTE
 #define AF_PACKET      PF_PACKET
+#define AF_CAN         PF_CAN
 #define AF_BLUETOOTH   PF_BLUETOOTH
 #define AF_IEEE802154  PF_IEEE802154
 #define AF_PKTRADIO    PF_PKTRADIO


[incubator-nuttx] 18/31: Added support for SO_TIMESTAMP in socketlayer and SocketCAN Cleanup FlexCAN driver driver Disabled workqueue based TX in FlexCAN

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch SocketCAN
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 9a537b0c8194872342ac2c3e783bbe0b40a9ee15
Author: Peter van der Perk <pe...@nxp.com>
AuthorDate: Wed Mar 11 14:32:52 2020 +0100

    Added support for SO_TIMESTAMP in socketlayer and SocketCAN
    Cleanup FlexCAN driver driver
    Disabled workqueue based TX in FlexCAN
---
 net/socket/recvmsg.c | 238 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 238 insertions(+)

diff --git a/net/socket/recvmsg.c b/net/socket/recvmsg.c
new file mode 100644
index 0000000..17d4dfe
--- /dev/null
+++ b/net/socket/recvmsg.c
@@ -0,0 +1,238 @@
+/****************************************************************************
+ * net/socket/recvmsg.c
+ *
+ *   Copyright (C) 2007-2009, 2011-2017, 2019 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <gn...@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <assert.h>
+#include <errno.h>
+
+#include <nuttx/cancelpt.h>
+#include <nuttx/net/net.h>
+
+#include "socket/socket.h"
+
+#ifdef CONFIG_NET_RECVMSG_CMSG
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: psock_recvmsg
+ *
+ * Description:
+ *   psock_recvfrom() receives messages from a socket, and may be used to
+ *   receive data on a socket whether or not it is connection-oriented.
+ *   This is an internal OS interface.  It is functionally equivalent to
+ *   recvfrom() except that:
+ *
+ *   - It is not a cancellation point,
+ *   - It does not modify the errno variable, and
+ *   - I accepts the internal socket structure as an input rather than an
+ *     task-specific socket descriptor.
+ *
+ * Input Parameters:
+ *   psock   - A pointer to a NuttX-specific, internal socket structure
+ *   msg      Buffer to receive msg
+ *   len     - Length of buffer
+ *   flags   - Receive flags
+ *
+ * Returned Value:
+ *   On success, returns the number of characters sent.  If no data is
+ *   available to be received and the peer has performed an orderly shutdown,
+ *   recv() will return 0.  Otherwise, on any failure, a negated errno value
+ *   is returned (see comments with send() for a list of appropriate errno
+ *   values).
+ *
+ ****************************************************************************/
+
+ssize_t psock_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg,
+                       int flags)
+{
+  /* Verify that non-NULL pointers were passed */
+  if (msg == NULL)
+    {
+      return -EINVAL;
+    }
+
+  if (msg->msg_iovlen != 1)
+    {
+      return -ENOTSUP;
+    }
+
+  /* Verify that the sockfd corresponds to valid, allocated socket */
+
+  if (psock == NULL || psock->s_crefs <= 0)
+    {
+      return -EBADF;
+    }
+
+  /* Let logic specific to this address family handle the recvfrom()
+   * operation.
+   */
+
+  DEBUGASSERT(psock->s_sockif != NULL &&
+              (psock->s_sockif->si_recvmsg != NULL ||
+               psock->s_sockif->si_recvfrom != NULL));
+
+  if(psock->s_sockif->si_recvmsg != NULL)
+    {
+	  return psock->s_sockif->si_recvmsg(psock, msg, flags);
+    }
+  else
+    {
+	  /* Socket doesn't implement si_recvmsg fallback to si_recvfrom */
+	  FAR void *buf             = msg->msg_iov->iov_base;
+	  FAR struct sockaddr *from = msg->msg_name;
+	  FAR socklen_t *fromlen    = (FAR socklen_t *)&msg->msg_namelen;
+	  size_t len                = msg->msg_iov->iov_len;
+	  return psock->s_sockif->si_recvfrom(psock, buf, len, flags, from, fromlen);
+    }
+
+}
+
+/****************************************************************************
+ * Name: nx_recvfrom
+ *
+ * Description:
+ *   nx_recvfrom() receives messages from a socket, and may be used to
+ *   receive data on a socket whether or not it is connection-oriented.
+ *   This is an internal OS interface.  It is functionally equivalent to
+ *   recvfrom() except that:
+ *
+ *   - It is not a cancellation point, and
+ *   - It does not modify the errno variable.
+ *
+ * Input Parameters:
+ *   sockfd  - Socket descriptor of socket
+ *   msg      Buffer to receive msg
+ *   len     - Length of buffer
+ *   flags   - Receive flags
+ *
+ * Returned Value:
+ *   On success, returns the number of characters sent.  If no data is
+ *   available to be received and the peer has performed an orderly shutdown,
+ *   recv() will return 0.  Otherwise, on any failure, a negated errno value
+ *   is returned (see comments with send() for a list of appropriate errno
+ *   values).
+ *
+ ****************************************************************************/
+
+ssize_t nx_recvmsg(int sockfd, FAR struct msghdr *msg, int flags)
+{
+  FAR struct socket *psock;
+
+  /* Get the underlying socket structure */
+
+  psock = sockfd_socket(sockfd);
+
+  /* Then let psock_recvmsg() do all of the work */
+
+  return psock_recvmsg(psock, msg, flags);
+}
+
+/****************************************************************************
+ * Function: recvmsg
+ *
+ * Description:
+ *   The recvmsg() call is identical to recvfrom() with a NULL from parameter.
+ *
+ * Parameters:
+ *   sockfd   Socket descriptor of socket
+ *   msg      Buffer to receive msg
+ *   len      Length of buffer
+ *   flags    Receive flags
+ *
+ * Returned Value:
+ *   On success, returns the number of characters received.  On  error,
+ *   -1 is returned, and errno is set appropriately:
+ *
+ *   EAGAIN
+ *     The socket is marked non-blocking and the receive operation would block,
+ *     or a receive timeout had been set and the timeout expired before data
+ *     was received.
+ *   EBADF
+ *     The argument sockfd is an invalid descriptor.
+ *   ECONNREFUSED
+ *     A remote host refused to allow the network connection (typically because
+ *     it is not running the requested service).
+ *   EFAULT
+ *     The receive buffer pointer(s) point outside the process's address space.
+ *   EINTR
+ *     The receive was interrupted by delivery of a signal before any data were
+ *     available.
+ *   EINVAL
+ *     Invalid argument passed.
+ *   ENOMEM
+ *     Could not allocate memory.
+ *   ENOTCONN
+ *     The socket is associated with a connection-oriented protocol and has
+ *     not been connected.
+ *   ENOTSOCK
+ *     The argument sockfd does not refer to a socket.
+ *
+ ****************************************************************************/
+
+ssize_t recvmsg(int sockfd, FAR struct msghdr *msg, int flags)
+{
+  FAR struct socket *psock;
+  ssize_t ret;
+
+  /* recvfrom() is a cancellation point */
+
+  enter_cancellation_point();
+
+  /* Get the underlying socket structure */
+
+  psock = sockfd_socket(sockfd);
+
+  /* Let psock_recvfrom() do all of the work */
+
+  ret = psock_recvmsg(psock, msg, flags);
+  if (ret < 0)
+    {
+      _SO_SETERRNO(psock, -ret);
+      ret = ERROR;
+    }
+
+  leave_cancellation_point();
+  return ret;
+}
+
+#endif /* CONFIG_NET_RECVMSG_CMSG */


[incubator-nuttx] 13/31: SocketCAN removed NET_TCP and NET_PKT dependencies

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch SocketCAN
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 37bc441597abee7580e291181197232f155673f8
Author: Peter van der Perk <pe...@nxp.com>
AuthorDate: Thu Mar 5 16:36:56 2020 +0100

    SocketCAN removed NET_TCP and NET_PKT dependencies
---
 fs/vfs/fs_write.c         |  2 +-
 include/nuttx/mm/iob.h    |  2 +-
 net/can/can_send.c        |  2 +-
 net/devif/Make.defs       |  2 +-
 net/devif/devif.h         | 23 ++++++++++++++++++++++-
 net/devif/devif_pktsend.c |  2 +-
 6 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/fs/vfs/fs_write.c b/fs/vfs/fs_write.c
index 6e9a379..ef5f137 100644
--- a/fs/vfs/fs_write.c
+++ b/fs/vfs/fs_write.c
@@ -149,7 +149,7 @@ ssize_t nx_write(int fd, FAR const void *buf, size_t nbytes)
 
   if ((unsigned int)fd >= CONFIG_NFILE_DESCRIPTORS)
     {
-#ifdef CONFIG_NET_TCP
+#if defined(CONFIG_NET_TCP) || defined(CONFIG_NET_CAN)
       /* Write to a socket descriptor is equivalent to send with flags == 0. */
 
       ret = nx_send(fd, buf, nbytes, 0);
diff --git a/include/nuttx/mm/iob.h b/include/nuttx/mm/iob.h
index 5903c50..e986105 100644
--- a/include/nuttx/mm/iob.h
+++ b/include/nuttx/mm/iob.h
@@ -221,7 +221,7 @@ enum iob_user_e
 #ifdef CONFIG_WIRELESS_BLUETOOTH
   IOBUSER_WIRELESS_BLUETOOTH,
 #endif
-#if defined(CONFIG_NET_CAN)
+#ifdef CONFIG_NET_CAN
   IOBUSER_NET_CAN_READAHEAD,
 #endif
   IOBUSER_GLOBAL,
diff --git a/net/can/can_send.c b/net/can/can_send.c
index 1d8677d..be621b4 100644
--- a/net/can/can_send.c
+++ b/net/can/can_send.c
@@ -119,7 +119,7 @@ static uint16_t psock_send_eventhandler(FAR struct net_driver_s *dev,
         {
           /* Copy the packet data into the device packet buffer and send it */
           //FIXME potentialy wrong function do we have a header??
-    	  devif_pkt_send(dev, pstate->snd_buffer, pstate->snd_buflen);
+    	  devif_can_send(dev, pstate->snd_buffer, pstate->snd_buflen);
           pstate->snd_sent = pstate->snd_buflen;
         }
 
diff --git a/net/devif/Make.defs b/net/devif/Make.defs
index 57aac89..492c7d8 100644
--- a/net/devif/Make.defs
+++ b/net/devif/Make.defs
@@ -67,7 +67,7 @@ NET_CSRCS += devif_pktsend.c
 endif
 
 ifeq ($(CONFIG_NET_CAN),y)
-NET_CSRCS += devif_pktsend.c
+NET_CSRCS += devif_cansend.c
 endif
 
 # Include network device interface build support
diff --git a/net/devif/devif.h b/net/devif/devif.h
index c54a68d..f924ebc 100644
--- a/net/devif/devif.h
+++ b/net/devif/devif.h
@@ -494,11 +494,32 @@ void devif_iob_send(FAR struct net_driver_s *dev, FAR struct iob_s *buf,
  *
  ****************************************************************************/
 
-#if defined(CONFIG_NET_PKT) || defined(CONFIG_NET_CAN)
+#if defined(CONFIG_NET_PKT)
 void devif_pkt_send(FAR struct net_driver_s *dev, FAR const void *buf,
                     unsigned int len);
 #endif
 
+/****************************************************************************
+ * Name: devif_can_send
+ *
+ * Description:
+ *   Called from socket logic in order to send a raw packet in response to
+ *   an xmit or poll request from the network interface driver.
+ *
+ *   This is almost identical to calling devif_send() except that the data to
+ *   be sent is copied into dev->d_buf (vs. dev->d_appdata), since there is
+ *   no header on the data.
+ *
+ * Assumptions:
+ *   This function must be called with the network locked.
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_NET_CAN)
+void devif_can_send(FAR struct net_driver_s *dev, FAR const void *buf,
+                    unsigned int len);
+#endif
+
 #undef EXTERN
 #ifdef __cplusplus
 }
diff --git a/net/devif/devif_pktsend.c b/net/devif/devif_pktsend.c
index a5d0515..465def2 100644
--- a/net/devif/devif_pktsend.c
+++ b/net/devif/devif_pktsend.c
@@ -45,7 +45,7 @@
 
 #include <nuttx/net/netdev.h>
 
-#if defined(CONFIG_NET_PKT) || defined(CONFIG_NET_CAN)
+#if defined(CONFIG_NET_PKT)
 
 /****************************************************************************
  * Pre-processor Definitions


[incubator-nuttx] 03/31: net/: Add WIP initial framework for SocketCAN sockets.

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch SocketCAN
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit c09248ecc6e6c9fa7da16b95f7e222b16ee086db
Author: Gregory Nutt <gn...@nuttx.org>
AuthorDate: Thu Feb 13 09:59:00 2020 -0600

    net/:  Add WIP initial framework for SocketCAN sockets.
---
 net/Kconfig             |   1 +
 net/Makefile            |   1 +
 net/can/Kconfig         |  26 ++
 net/can/Make.defs       |  32 ++
 net/can/can.h           | 154 +++++++++
 net/can/can_conn.c      | 225 ++++++++++++++
 net/can/can_sockif.c    | 810 ++++++++++++++++++++++++++++++++++++++++++++++++
 net/net_initialize.c    |   7 +
 net/socket/net_sockif.c |   7 +
 9 files changed, 1263 insertions(+)

diff --git a/net/Kconfig b/net/Kconfig
index fed3d01..70cacf6 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -344,6 +344,7 @@ source "net/socket/Kconfig"
 source "net/inet/Kconfig"
 source "net/pkt/Kconfig"
 source "net/local/Kconfig"
+source "net/can/Kconfig"
 source "net/netlink/Kconfig"
 source "net/tcp/Kconfig"
 source "net/udp/Kconfig"
diff --git a/net/Makefile b/net/Makefile
index 077d035..f8ffe85 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -52,6 +52,7 @@ include igmp/Make.defs
 include pkt/Make.defs
 include local/Make.defs
 include mld/Make.defs
+include can/Make.defs
 include netlink/Make.defs
 include tcp/Make.defs
 include udp/Make.defs
diff --git a/net/can/Kconfig b/net/can/Kconfig
new file mode 100644
index 0000000..2ae1f7b
--- /dev/null
+++ b/net/can/Kconfig
@@ -0,0 +1,26 @@
+#
+# For a description of the syntax of this configuration file,
+# see the file kconfig-language.txt in the NuttX tools repository.
+#
+
+menu "SocketCAN Support"
+
+config NET_CAN
+	bool "SocketCAN support"
+	default n
+	---help---
+		Enable support for SocketCAN sockets that will permit.
+
+		This logic is a WIP.  Currently only fragmentary support is
+		available, not enough to actually do anything of consequence.
+
+if NET_CAN
+
+config CAN_CONNS
+	int "Number of CAN connections"
+	default 4
+	---help---
+		Maximum number of CAN connections (all tasks).
+
+endif # NET_CAN
+endmenu # CAN Socket Support
diff --git a/net/can/Make.defs b/net/can/Make.defs
new file mode 100644
index 0000000..bb9ef9f
--- /dev/null
+++ b/net/can/Make.defs
@@ -0,0 +1,32 @@
+############################################################################
+# net/can/Make.defs
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.  The
+# ASF licenses this file to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance with the
+# License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+############################################################################
+
+# Logic specific to SocketCAN socket support
+
+ifeq ($(CONFIG_NET_CAN),y)
+
+SOCK_CSRCS += can_sockif.c
+NET_CSRCS += can_conn.c
+
+# Include can build support
+
+DEPPATH += --dep-path can
+VPATH += :can
+endif
diff --git a/net/can/can.h b/net/can/can.h
new file mode 100644
index 0000000..6f41ce9
--- /dev/null
+++ b/net/can/can.h
@@ -0,0 +1,154 @@
+/****************************************************************************
+ * net/can/can.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __NET_CAN_CAN_H
+#define __NET_CAN_CAN_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <poll.h>
+
+#include <netpacket/can.h>
+#include <nuttx/semaphore.h>
+
+#include "devif/devif.h"
+#include "socket/socket.h"
+
+#ifdef CONFIG_NET_CAN
+
+/****************************************************************************
+ * Public Type Definitions
+ ****************************************************************************/
+
+/* This "connection" structure describes the underlying state of the socket. */
+
+struct can_conn_s
+{
+  /* Common prologue of all connection structures. */
+
+  dq_entry_t node;                   /* Supports a doubly linked list */
+
+  /* This is a list of NetLink connection callbacks.  Each callback
+   * represents a thread that is stalled, waiting for a device-specific
+   * event.
+   */
+
+  FAR struct devif_callback_s *list; /* NetLink callbacks */
+
+  /* CAN-specific content follows */
+
+  uint8_t protocol;                  /* Selected CAN protocol */
+  int16_t crefs;                     /* Reference count */
+
+  /* poll() support */
+
+  FAR sem_t *pollsem;                /* Used to wakeup poll() */
+  FAR pollevent_t *pollevent;        /* poll() wakeup event */
+};
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+#ifdef __cplusplus
+#  define EXTERN extern "C"
+extern "C"
+{
+#else
+#  define EXTERN extern
+#endif
+
+EXTERN const struct sock_intf_s g_can_sockif;
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+struct sockaddr_can;  /* Forward reference */
+
+/****************************************************************************
+ * Name: can_initialize()
+ *
+ * Description:
+ *   Initialize the NetLink connection structures.  Called once and only
+ *   from the networking layer.
+ *
+ ****************************************************************************/
+
+void can_initialize(void);
+
+/****************************************************************************
+ * Name: can_alloc()
+ *
+ * Description:
+ *   Allocate a new, uninitialized NetLink connection structure.  This is
+ *   normally something done by the implementation of the socket() API
+ *
+ ****************************************************************************/
+
+FAR struct can_conn_s *can_alloc(void);
+
+/****************************************************************************
+ * Name: can_free()
+ *
+ * Description:
+ *   Free a NetLink connection structure that is no longer in use. This should
+ *   be done by the implementation of close().
+ *
+ ****************************************************************************/
+
+void can_free(FAR struct can_conn_s *conn);
+
+/****************************************************************************
+ * Name: can_nextconn()
+ *
+ * Description:
+ *   Traverse the list of allocated NetLink connections
+ *
+ * Assumptions:
+ *   This function is called from NetLink device logic.
+ *
+ ****************************************************************************/
+
+FAR struct can_conn_s *can_nextconn(FAR struct can_conn_s *conn);
+
+/****************************************************************************
+ * Name: can_active()
+ *
+ * Description:
+ *   Find a connection structure that is the appropriate connection for the
+ *   provided NetLink address
+ *
+ ****************************************************************************/
+
+FAR struct can_conn_s *can_active(FAR struct sockaddr_can *addr);
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CONFIG_NET_CAN */
+#endif /* __NET_CAN_CAN_H */
diff --git a/net/can/can_conn.c b/net/can/can_conn.c
new file mode 100644
index 0000000..77733b3
--- /dev/null
+++ b/net/can/can_conn.c
@@ -0,0 +1,225 @@
+/****************************************************************************
+ * net/can/can_conn.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <string.h>
+#include <queue.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <arch/irq.h>
+
+#include <nuttx/kmalloc.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/net/netconfig.h>
+#include <nuttx/net/net.h>
+
+#include "utils/utils.h"
+#include "can/can.h"
+
+#ifdef CONFIG_NET_CAN
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* The array containing all NetLink connections. */
+
+static struct can_conn_s g_can_connections[CONFIG_CAN_CONNS];
+
+/* A list of all free NetLink connections */
+
+static dq_queue_t g_free_can_connections;
+static sem_t g_free_sem;
+
+/* A list of all allocated NetLink connections */
+
+static dq_queue_t g_active_can_connections;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: _can_semtake() and _can_semgive()
+ *
+ * Description:
+ *   Take/give semaphore
+ *
+ ****************************************************************************/
+
+static void _can_semtake(FAR sem_t *sem)
+{
+  net_lockedwait_uninterruptible(sem);
+}
+
+static void _can_semgive(FAR sem_t *sem)
+{
+  nxsem_post(sem);
+}
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: can_initialize()
+ *
+ * Description:
+ *   Initialize the User Socket connection structures.  Called once and only
+ *   from the networking layer.
+ *
+ ****************************************************************************/
+
+void can_initialize(void)
+{
+  int i;
+
+  /* Initialize the queues */
+
+  dq_init(&g_free_can_connections);
+  dq_init(&g_active_can_connections);
+  nxsem_init(&g_free_sem, 0, 1);
+
+  for (i = 0; i < CONFIG_CAN_CONNS; i++)
+    {
+      FAR struct can_conn_s *conn = &g_can_connections[i];
+
+      /* Mark the connection closed and move it to the free list */
+
+      memset(conn, 0, sizeof(*conn));
+      dq_addlast(&conn->node, &g_free_can_connections);
+    }
+}
+
+/****************************************************************************
+ * Name: can_alloc()
+ *
+ * Description:
+ *   Allocate a new, uninitialized NetLink connection structure.  This is
+ *   normally something done by the implementation of the socket() API
+ *
+ ****************************************************************************/
+
+FAR struct can_conn_s *can_alloc(void)
+{
+  FAR struct can_conn_s *conn;
+
+  /* The free list is protected by a semaphore (that behaves like a mutex). */
+
+  _can_semtake(&g_free_sem);
+  conn = (FAR struct can_conn_s *)dq_remfirst(&g_free_can_connections);
+  if (conn != NULL)
+    {
+      /* Make sure that the connection is marked as uninitialized */
+
+      memset(conn, 0, sizeof(*conn));
+
+      /* Enqueue the connection into the active list */
+
+      dq_addlast(&conn->node, &g_active_can_connections);
+    }
+
+  _can_semgive(&g_free_sem);
+  return conn;
+}
+
+/****************************************************************************
+ * Name: can_free()
+ *
+ * Description:
+ *   Free a NetLink connection structure that is no longer in use. This should
+ *   be done by the implementation of close().
+ *
+ ****************************************************************************/
+
+void can_free(FAR struct can_conn_s *conn)
+{
+  /* The free list is protected by a semaphore (that behaves like a mutex). */
+
+  DEBUGASSERT(conn->crefs == 0);
+
+  _can_semtake(&g_free_sem);
+
+  /* Remove the connection from the active list */
+
+  dq_rem(&conn->node, &g_active_can_connections);
+
+  /* Reset structure */
+
+  memset(conn, 0, sizeof(*conn));
+
+  /* Free the connection */
+
+  dq_addlast(&conn->node, &g_free_can_connections);
+  _can_semgive(&g_free_sem);
+}
+
+/****************************************************************************
+ * Name: can_nextconn()
+ *
+ * Description:
+ *   Traverse the list of allocated NetLink connections
+ *
+ * Assumptions:
+ *   This function is called from NetLink device logic.
+ *
+ ****************************************************************************/
+
+FAR struct can_conn_s *can_nextconn(FAR struct can_conn_s *conn)
+{
+  if (conn == NULL)
+    {
+      return (FAR struct can_conn_s *)g_active_can_connections.head;
+    }
+  else
+    {
+      return (FAR struct can_conn_s *)conn->node.flink;
+    }
+}
+
+/****************************************************************************
+ * Name: can_active
+ *
+ * Description:
+ *   Find a connection structure that is the appropriate connection for the
+ *   provided NetLink address
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+FAR struct can_conn_s *can_active(FAR struct sockaddr_can *addr)
+{
+  /* This function is used to handle routing of incoming messages to sockets
+   * connected to the address.  There is no such use case for NetLink
+   * sockets.
+   */
+
+  return NULL;
+}
+
+#endif /* CONFIG_NET_CAN */
diff --git a/net/can/can_sockif.c b/net/can/can_sockif.c
new file mode 100644
index 0000000..b7e3fe6
--- /dev/null
+++ b/net/can/can_sockif.c
@@ -0,0 +1,810 @@
+/****************************************************************************
+ * net/can/can_sockif.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdbool.h>
+#include <string.h>
+#include <poll.h>
+#include <sched.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/kmalloc.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/wqueue.h>
+#include <nuttx/net/net.h>
+
+#include "can/can.h"
+
+#ifdef CONFIG_NET_CAN
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int  can_setup(FAR struct socket *psock, int protocol);
+static sockcaps_t can_sockcaps(FAR struct socket *psock);
+static void can_addref(FAR struct socket *psock);
+static int  can_bind(FAR struct socket *psock,
+              FAR const struct sockaddr *addr, socklen_t addrlen);
+static int  can_getsockname(FAR struct socket *psock,
+              FAR struct sockaddr *addr, FAR socklen_t *addrlen);
+static int  can_getpeername(FAR struct socket *psock,
+              FAR struct sockaddr *addr, FAR socklen_t *addrlen);
+static int  can_listen(FAR struct socket *psock, int backlog);
+static int  can_connect(FAR struct socket *psock,
+              FAR const struct sockaddr *addr, socklen_t addrlen);
+static int  can_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
+              FAR socklen_t *addrlen, FAR struct socket *newsock);
+static int  can_poll(FAR struct socket *psock, FAR struct pollfd *fds,
+              bool setup);
+static ssize_t can_send(FAR struct socket *psock,
+              FAR const void *buf, size_t len, int flags);
+static ssize_t can_sendto(FAR struct socket *psock, FAR const void *buf,
+              size_t len, int flags, FAR const struct sockaddr *to,
+              socklen_t tolen);
+static ssize_t can_recvfrom(FAR struct socket *psock, FAR void *buf,
+              size_t len, int flags, FAR struct sockaddr *from,
+              FAR socklen_t *fromlen);
+static int can_close(FAR struct socket *psock);
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+const struct sock_intf_s g_can_sockif =
+{
+  can_setup,        /* si_setup */
+  can_sockcaps,     /* si_sockcaps */
+  can_addref,       /* si_addref */
+  can_bind,         /* si_bind */
+  can_getsockname,  /* si_getsockname */
+  can_getpeername,  /* si_getpeername */
+  can_listen,       /* si_listen */
+  can_connect,      /* si_connect */
+  can_accept,       /* si_accept */
+  can_poll,         /* si_poll */
+  can_send,         /* si_send */
+  can_sendto,       /* si_sendto */
+#ifdef CONFIG_NET_SENDFILE
+  NULL,             /* si_sendfile */
+#endif
+  can_recvfrom,     /* si_recvfrom */
+  can_close         /* si_close */
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: inet_setup
+ *
+ * Description:
+ *   Called for socket() to verify that the provided socket type and
+ *   protocol are usable by this address family.  Perform any family-
+ *   specific socket fields.
+ *
+ * Input Parameters:
+ *   psock    - A pointer to a user allocated socket structure to be
+ *              initialized.
+ *   protocol - NetLink socket protocol (see sys/socket.h)
+ *
+ * Returned Value:
+ *   Zero (OK) is returned on success.  Otherwise, a negated errno value is
+ *   returned.
+ *
+ ****************************************************************************/
+
+static int can_setup(FAR struct socket *psock, int protocol)
+{
+  int domain = psock->s_domain;
+  int type = psock->s_type;
+
+  /* Verify that the protocol is supported */
+
+  DEBUGASSERT((unsigned int)protocol <= UINT8_MAX);
+
+  switch (protocol)
+    {
+      case CAN_RAW:      /* RAW sockets */
+      case CAN_BCM:      /* Broadcast Manager */
+      case CAN_TP16:     /* VAG Transport Protocol v1.6 */
+      case CAN_TP20:     /* VAG Transport Protocol v2.0 */
+      case CAN_MCNET:    /* Bosch MCNet */
+      case CAN_ISOTP:    /* ISO 15765-2 Transport Protocol */
+      case CAN_J1939:    /* SAE J1939 */
+        break;
+
+      default:
+        return -EPROTONOSUPPORT;
+    }
+
+  /* Verify the socket type (domain should always be PF_CAN here) */
+
+  if (domain == PF_CAN && (type == SOCK_RAW || type == SOCK_DGRAM))
+    {
+      /* Allocate the NetLink socket connection structure and save it in the
+       * new socket instance.
+       */
+
+      FAR struct can_conn_s *conn = can_alloc();
+      if (conn == NULL)
+        {
+          /* Failed to reserve a connection structure */
+
+          return -ENOMEM;
+        }
+
+      /* Initialize the connection instance */
+
+      conn->protocol = (uint8_t)protocol;
+
+      /* Set the reference count on the connection structure.  This
+       * reference count will be incremented only if the socket is
+       * dup'ed
+       */
+
+      conn->crefs = 1;
+
+      /* Attach the connection instance to the socket */
+
+      psock->s_conn = conn;
+      return OK;
+    }
+
+  return -EPROTONOSUPPORT;
+}
+
+/****************************************************************************
+ * Name: can_sockcaps
+ *
+ * Description:
+ *   Return the bit encoded capabilities of this socket.
+ *
+ * Input Parameters:
+ *   psock - Socket structure of the socket whose capabilities are being
+ *           queried.
+ *
+ * Returned Value:
+ *   The non-negative set of socket capabilities is returned.
+ *
+ ****************************************************************************/
+
+static sockcaps_t can_sockcaps(FAR struct socket *psock)
+{
+  /* Permit vfcntl to set socket to non-blocking */
+
+  return SOCKCAP_NONBLOCKING;
+}
+
+/****************************************************************************
+ * Name: can_addref
+ *
+ * Description:
+ *   Increment the reference count on the underlying connection structure.
+ *
+ * Input Parameters:
+ *   psock - Socket structure of the socket whose reference count will be
+ *           incremented.
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void can_addref(FAR struct socket *psock)
+{
+  FAR struct can_conn_s *conn;
+
+  DEBUGASSERT(psock != NULL && psock->s_conn != NULL);
+
+  conn = psock->s_conn;
+  DEBUGASSERT(conn->crefs > 0 && conn->crefs < 255);
+  conn->crefs++;
+}
+
+/****************************************************************************
+ * Name: can_bind
+ *
+ * Description:
+ *   can_bind() gives the socket 'conn' the local address 'addr'. 'addr'
+ *   is 'addrlen' bytes long. Traditionally, this is called "assigning a name
+ *   to a socket." When a socket is created with socket, it exists in a name
+ *   space (address family) but has no name assigned.
+ *
+ * Input Parameters:
+ *   conn     NetLink socket connection structure
+ *   addr     Socket local address
+ *   addrlen  Length of 'addr'
+ *
+ * Returned Value:
+ *   0 on success; -1 on error with errno set appropriately
+ *
+ *   EACCES
+ *     The address is protected, and the user is not the superuser.
+ *   EADDRINUSE
+ *     The given address is already in use.
+ *   EINVAL
+ *     The socket is already bound to an address.
+ *   ENOTSOCK
+ *     psock is a descriptor for a file, not a socket.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static int can_bind(FAR struct socket *psock,
+                        FAR const struct sockaddr *addr, socklen_t addrlen)
+{
+  FAR struct sockaddr_can *canaddr;
+  FAR struct can_conn_s *conn;
+
+  DEBUGASSERT(psock != NULL && psock->s_conn != NULL && addr != NULL &&
+              addrlen >= sizeof(struct sockaddr_can));
+
+  /* Save the address information in the connection structure */
+
+  canaddr         = (FAR struct sockaddr_can *)addr;
+  conn            = (FAR struct can_conn_s *)psock->s_conn;
+#warning Missing logic
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: can_getsockname
+ *
+ * Description:
+ *   The getsockname() function retrieves the locally-bound name of the
+ *   specified socket, stores this address in the sockaddr structure pointed
+ *   to by the 'addr' argument, and stores the length of this address in the
+ *   object pointed to by the 'addrlen' argument.
+ *
+ *   If the actual length of the address is greater than the length of the
+ *   supplied sockaddr structure, the stored address will be truncated.
+ *
+ *   If the socket has not been bound to a local name, the value stored in
+ *   the object pointed to by address is unspecified.
+ *
+ * Input Parameters:
+ *   conn     NetLink socket connection structure
+ *   addr     sockaddr structure to receive data [out]
+ *   addrlen  Length of sockaddr structure [in/out]
+ *
+ ****************************************************************************/
+
+static int can_getsockname(FAR struct socket *psock,
+                               FAR struct sockaddr *addr,
+                               FAR socklen_t *addrlen)
+{
+  FAR struct sockaddr_can *canaddr;
+
+  DEBUGASSERT(psock != NULL && psock->s_conn != NULL && addr != NULL &&
+              addrlen != NULL && *addrlen >= sizeof(struct sockaddr_can));
+
+  /* Return the address information in the address structure */
+
+  canaddr = (FAR struct sockaddr_can *)addr;
+  memset(canaddr, 0, sizeof(struct sockaddr_can));
+
+  canaddr->can_family = AF_CAN;
+
+  if (_SS_ISBOUND(psock->s_flags))
+    {
+      FAR struct can_conn_s *conn;
+
+      conn            = (FAR struct can_conn_s *)psock->s_conn;
+#warning Missing logic
+    }
+
+  *addrlen = sizeof(struct sockaddr_can);
+  return OK;
+}
+
+/****************************************************************************
+ * Name: can_getpeername
+ *
+ * Description:
+ *   The can_getpeername() function retrieves the remote-connected name
+ *   of the specified packet socket, stores this address in the sockaddr
+ *   structure pointed to by the 'addr' argument, and stores the length of
+ *   this address in the object pointed to by the 'addrlen' argument.
+ *
+ *   If the actual length of the address is greater than the length of the
+ *   supplied sockaddr structure, the stored address will be truncated.
+ *
+ *   If the socket has not been bound to a local name, the value stored in
+ *   the object pointed to by address is unspecified.
+ *
+ * Parameters:
+ *   psock    Socket structure of the socket to be queried
+ *   addr     sockaddr structure to receive data [out]
+ *   addrlen  Length of sockaddr structure [in/out]
+ *
+ * Returned Value:
+ *   On success, 0 is returned, the 'addr' argument points to the address
+ *   of the socket, and the 'addrlen' argument points to the length of the
+ *   address.  Otherwise, a negated errno value is returned.  See
+ *   getpeername() for the list of appropriate error numbers.
+ *
+ ****************************************************************************/
+
+static int can_getpeername(FAR struct socket *psock,
+                               FAR struct sockaddr *addr,
+                               FAR socklen_t *addrlen)
+{
+#warning Missing logic
+  return -EOPNOTSUPP;  /* Or maybe return -EAFNOSUPPORT; */
+}
+
+/****************************************************************************
+ * Name: can_listen
+ *
+ * Description:
+ *   To accept connections, a socket is first created with psock_socket(), a
+ *   willingness to accept incoming connections and a queue limit for
+ *   incoming connections are specified with psock_listen(), and then the
+ *   connections are accepted with psock_accept().  For the case of AFINET
+ *   and AFINET6 sockets, psock_listen() calls this function.  The
+ *   psock_listen() call applies only to sockets of type SOCK_STREAM or
+ *   SOCK_SEQPACKET.
+ *
+ * Input Parameters:
+ *   psock    Reference to an internal, bound socket structure.
+ *   backlog  The maximum length the queue of pending connections may grow.
+ *            If a connection request arrives with the queue full, the client
+ *            may receive an error with an indication of ECONNREFUSED or,
+ *            if the underlying protocol supports retransmission, the request
+ *            may be ignored so that retries succeed.
+ *
+ * Returned Value:
+ *   On success, zero is returned. On error, a negated errno value is
+ *   returned.  See list() for the set of appropriate error values.
+ *
+ ****************************************************************************/
+
+static int can_listen(FAR struct socket *psock, int backlog)
+{
+#warning Missing logic
+  return -EOPNOTSUPP;
+}
+
+/****************************************************************************
+ * Name: can_connect
+ *
+ * Description:
+ *   Perform a can connection
+ *
+ * Input Parameters:
+ *   psock   A reference to the socket structure of the socket to be connected
+ *   addr    The address of the remote server to connect to
+ *   addrlen Length of address buffer
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static int can_connect(FAR struct socket *psock,
+                           FAR const struct sockaddr *addr,
+                           socklen_t addrlen)
+{
+#warning Missing logic
+  return -EOPNOTSUPP;
+}
+
+/****************************************************************************
+ * Name: can_accept
+ *
+ * Description:
+ *   The can_accept function is used with connection-based socket
+ *   types (SOCK_STREAM, SOCK_SEQPACKET and SOCK_RDM). It extracts the first
+ *   connection request on the queue of pending connections, creates a new
+ *   connected socket with mostly the same properties as 'sockfd', and
+ *   allocates a new socket descriptor for the socket, which is returned. The
+ *   newly created socket is no longer in the listening state. The original
+ *   socket 'sockfd' is unaffected by this call.  Per file descriptor flags
+ *   are not inherited across an inet_accept.
+ *
+ *   The 'sockfd' argument is a socket descriptor that has been created with
+ *   socket(), bound to a local address with bind(), and is listening for
+ *   connections after a call to listen().
+ *
+ *   On return, the 'addr' structure is filled in with the address of the
+ *   connecting entity. The 'addrlen' argument initially contains the size
+ *   of the structure pointed to by 'addr'; on return it will contain the
+ *   actual length of the address returned.
+ *
+ *   If no pending connections are present on the queue, and the socket is
+ *   not marked as non-blocking, inet_accept blocks the caller until a
+ *   connection is present. If the socket is marked non-blocking and no
+ *   pending connections are present on the queue, inet_accept returns
+ *   EAGAIN.
+ *
+ * Input Parameters:
+ *   psock    Reference to the listening socket structure
+ *   addr     Receives the address of the connecting client
+ *   addrlen  Input:  Allocated size of 'addr'
+ *            Return: Actual size returned size of 'addr'
+ *   newsock  Location to return the accepted socket information.
+ *
+ * Returned Value:
+ *   Returns 0 (OK) on success.  On failure, it returns a negated errno
+ *   value.  See accept() for a description of the appropriate error value.
+ *
+ * Assumptions:
+ *   The network is locked.
+ *
+ ****************************************************************************/
+
+static int can_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
+                          FAR socklen_t *addrlen, FAR struct socket *newsock)
+{
+#warning Missing logic
+  return -EOPNOTSUPP;
+}
+
+/****************************************************************************
+ * Name: can_poll
+ *
+ * Description:
+ *   The standard poll() operation redirects operations on socket descriptors
+ *   to this function.
+ *
+ *     POLLUP:  Will never be reported
+ *     POLLERR: Reported in the event of any failure.
+ *     POLLOUT: Always reported if requested.
+ *     POLLIN:  Reported if requested but only when pending response data is
+ *              available
+ *
+ * Input Parameters:
+ *   psock - An instance of the internal socket structure.
+ *   fds   - The structure describing the events to be monitored.
+ *   setup - true: Setup up the poll; false: Tear down the poll
+ *
+ * Returned Value:
+ *  0: Success; Negated errno on failure
+ *
+ ****************************************************************************/
+
+static int can_poll(FAR struct socket *psock, FAR struct pollfd *fds,
+                        bool setup)
+{
+  FAR struct can_conn_s *conn;
+  int ret;
+
+  DEBUGASSERT(psock != NULL && psock->s_conn != NULL);
+  conn = (FAR struct can_conn_s *)psock->s_conn;
+
+  /* Check if we are setting up or tearing down the poll */
+
+  if (setup)
+    {
+      /* If POLLOUT is selected, return immediately (maybe) */
+
+      pollevent_t revents = POLLOUT;
+
+      /* If POLLIN is selected and a response is available, return
+       * immediately if POLLIN and/or POLLIN are included in the
+       * requested event set.
+       */
+
+      net_lock();
+
+#warning Missing logic
+
+      revents &= fds->events;
+      if (revents != 0)
+        {
+          fds->revents = revents;
+          nxsem_post(fds->sem);
+          net_unlock();
+          return OK;
+        }
+
+      /* Set up to be notified when a response is available if POLLIN is
+       * requested.
+       */
+
+      if ((fds->events & POLLIN) != 0)
+        {
+          /* Some limitations:  There can be only a single outstanding POLLIN
+           * on the CAN connection.
+           */
+
+          if (conn->pollsem != NULL || conn->pollevent != NULL)
+            {
+              nerr("ERROR: Multiple polls() on socket not supported.\n");
+              net_unlock();
+              return -EBUSY;
+            }
+
+          /* Set up the notification */
+
+          conn->pollsem    = fds->sem;
+          conn->pollevent  = &fds->revents;
+
+#warning Missing logic
+
+          if (ret < 0)
+            {
+              /* Failed to set up notification */
+
+              conn->pollsem   = NULL;
+              conn->pollevent = NULL;
+            }
+          else
+            {
+              /* Setup to receive a notification when CAN data is available */
+
+#warning Missing logic
+
+              ret = OK;
+            }
+        }
+
+      /* Set up to be notified when we are able to send CAN data without
+       * waiting.
+       */
+
+      else if ((fds->events & POLLOUT) != 0)
+        {
+        }
+      else
+        {
+          /* There will not be any wakeups coming?  Probably an error? */
+
+          ret = OK;
+        }
+
+      net_unlock();
+    }
+  else
+    {
+      /* Cancel any response notifications */
+
+      conn->pollsem   = NULL;
+      conn->pollevent = NULL;
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: can_send
+ *
+ * Description:
+ *   The can_send() call may be used only when the socket is in
+ *   a connected state  (so that the intended recipient is known).
+ *
+ * Input Parameters:
+ *   psock - An instance of the internal socket structure.
+ *   buf   - Data to send
+ *   len   - Length of data to send
+ *   flags - Send flags (ignored)
+ *
+ * Returned Value:
+ *   On success, returns the number of characters sent.  On  error, a negated
+ *   errno value is returned (see send() for the list of appropriate error
+ *   values.
+ *
+ ****************************************************************************/
+
+static ssize_t can_send(FAR struct socket *psock, FAR const void *buf,
+                            size_t len, int flags)
+{
+  DEBUGASSERT(psock != NULL && psock->s_conn != NULL && buf != NULL);
+
+  /* The socket must be connected in order to use send */
+
+  if (_SS_ISBOUND(psock->s_flags))
+    {
+      FAR struct can_conn_s *conn;
+      struct sockaddr_can canaddr;
+
+      /* Get the underlying connection structure */
+
+      conn               = (FAR struct can_conn_s *)psock->s_conn;
+
+      /* Format the address */
+
+      canaddr.can_family = AF_CAN;
+#warning Missing logic
+
+      /* Then let sendto() perform the actual send operation */
+
+      return can_sendto(psock, buf, len, flags,
+                            (FAR const struct sockaddr *)&canaddr,
+                            sizeof(struct sockaddr_can));
+    }
+
+  /* EDESTADDRREQ.  Signifies that the socket is not connection-mode and no
+   * peer address is set.
+   */
+
+  return -EDESTADDRREQ;
+}
+
+/****************************************************************************
+ * Name: can_sendto
+ *
+ * Description:
+ *   If sendto() is used on a connection-mode (SOCK_STREAM, SOCK_SEQPACKET)
+ *   socket, the parameters to and 'tolen' are ignored (and the error EISCONN
+ *   may be returned when they are not NULL and 0), and the error ENOTCONN is
+ *   returned when the socket was not actually connected.
+ *
+ * Input Parameters:
+ *   psock    A reference to the socket structure of the socket to be connected
+ *   buf      Data to send
+ *   len      Length of data to send
+ *   flags    Send flags (ignored)
+ *   to       Address of recipient
+ *   tolen    The length of the address structure
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static ssize_t can_sendto(FAR struct socket *psock, FAR const void *buf,
+                              size_t len, int flags,
+                              FAR const struct sockaddr *to, socklen_t tolen)
+{
+  FAR struct can_conn_s *conn;
+  int ret;
+
+  DEBUGASSERT(psock != NULL && psock->s_conn != NULL && buf != NULL &&
+              to != NULL && tolen >= sizeof(struct sockaddr_can));
+
+  conn = (FAR struct can_conn_s *)psock->s_conn;
+#warning Missing logic
+
+  switch (conn->protocol)
+    {
+#warning Missing logic
+
+      default:
+       ret = -EOPNOTSUPP;
+       break;
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: can_recvfrom
+ *
+ * Description:
+ *   recvfrom() receives messages from a socket, and may be used to receive
+ *   data on a socket whether or not it is connection-oriented.
+ *
+ *   If from is not NULL, and the underlying protocol provides the source
+ *   address, this source address is filled in. The argument 'fromlen'
+ *   initialized to the size of the buffer associated with from, and modified
+ *   on return to indicate the actual size of the address stored there.
+ *
+ * Input Parameters:
+ *   psock    A pointer to a NuttX-specific, internal socket structure
+ *   buf      Buffer to receive data
+ *   len      Length of buffer
+ *   flags    Receive flags (ignored)
+ *   from     Address of source (may be NULL)
+ *   fromlen  The length of the address structure
+ *
+ ****************************************************************************/
+
+static ssize_t can_recvfrom(FAR struct socket *psock, FAR void *buf,
+                                size_t len, int flags,
+                                FAR struct sockaddr *from,
+                                FAR socklen_t *fromlen)
+{
+  FAR struct can_conn_s *conn;
+  int ret;
+
+  DEBUGASSERT(psock != NULL && psock->s_conn != NULL && buf != NULL);
+  DEBUGASSERT(from == NULL ||
+              (fromlen != NULL && *fromlen >= sizeof(struct sockaddr_can)));
+
+  conn = (FAR struct can_conn_s *)psock->s_conn;
+#warning Missing logic
+
+  switch (conn->protocol)
+    {
+#warning Missing logic
+
+      default:
+       ret = -EOPNOTSUPP;
+       break;
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: can_close
+ *
+ * Description:
+ *   Performs the close operation on a NetLink socket instance
+ *
+ * Input Parameters:
+ *   psock   Socket instance
+ *
+ * Returned Value:
+ *   0 on success; -1 on error with errno set appropriately.
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+static int can_close(FAR struct socket *psock)
+{
+  FAR struct can_conn_s *conn = psock->s_conn;
+  int ret = OK;
+
+  /* Perform some pre-close operations for the CAN socket type. */
+
+  /* Is this the last reference to the connection structure (there
+   * could be more if the socket was dup'ed).
+   */
+
+  if (conn->crefs <= 1)
+    {
+      /* Yes... inform user-space daemon of socket close. */
+
+#warning Missing logic
+
+      /* Free the connection structure */
+
+      conn->crefs = 0;
+      can_free(psock->s_conn);
+
+      if (ret < 0)
+        {
+          /* Return with error code, but free resources. */
+
+          nerr("ERROR: can_close failed: %d\n", ret);
+          return ret;
+        }
+    }
+  else
+    {
+      /* No.. Just decrement the reference count */
+
+      conn->crefs--;
+    }
+
+  return ret;
+}
+
+#endif /* CONFIG_NET_CAN */
diff --git a/net/net_initialize.c b/net/net_initialize.c
index eb82777..bedc4e3 100644
--- a/net/net_initialize.c
+++ b/net/net_initialize.c
@@ -59,6 +59,7 @@
 #include "bluetooth/bluetooth.h"
 #include "ieee802154/ieee802154.h"
 #include "local/local.h"
+#include "can/can.h"
 #include "netlink/netlink.h"
 #include "igmp/igmp.h"
 #include "route/route.h"
@@ -158,6 +159,12 @@ void net_initialize(void)
   local_initialize();
 #endif
 
+#ifdef CONFIG_NET_CAN
+  /* Initialize SocketCAN support */
+
+  can_initialize();
+#endif
+
 #ifdef CONFIG_NET_NETLINK
   /* Initialize the Netlink IPC support */
 
diff --git a/net/socket/net_sockif.c b/net/socket/net_sockif.c
index 01e8368..cc956d8 100644
--- a/net/socket/net_sockif.c
+++ b/net/socket/net_sockif.c
@@ -47,6 +47,7 @@
 
 #include "inet/inet.h"
 #include "local/local.h"
+#include "can/can.h"
 #include "netlink/netlink.h"
 #include "pkt/pkt.h"
 #include "bluetooth/bluetooth.h"
@@ -104,6 +105,12 @@ net_sockif(sa_family_t family, int type, int protocol)
       break;
 #endif
 
+#ifdef CONFIG_NET_CAN
+    case PF_CAN:
+      sockif = &g_can_sockif;
+      break;
+#endif
+
 #ifdef CONFIG_NET_NETLINK
     case PF_NETLINK:
       sockif = &g_netlink_sockif;


[incubator-nuttx] 30/31: Backport code style fixes

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch SocketCAN
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit b3ba45b36f11fa06f6e6fe153155819e098fc8b2
Author: Peter van der Perk <pe...@nxp.com>
AuthorDate: Wed Mar 18 12:18:30 2020 +0100

    Backport code style fixes
---
 include/nuttx/wqueue.h |   2 +-
 net/can/can.h          |  13 ++--
 net/can/can_recvfrom.c | 191 ++++++++++++++++++++++++++-----------------------
 3 files changed, 108 insertions(+), 98 deletions(-)

diff --git a/include/nuttx/wqueue.h b/include/nuttx/wqueue.h
index 5ea8dfc..ea7563c 100644
--- a/include/nuttx/wqueue.h
+++ b/include/nuttx/wqueue.h
@@ -280,7 +280,7 @@ enum work_evtype_e
   WORK_TCP_DISCONNECT,   /* Notify loss of TCP connection */
   WORK_UDP_READAHEAD,    /* Notify that UDP read-ahead data is available */
   WORK_UDP_WRITEBUFFER,  /* Notify that UDP write buffer is empty */
-  WORK_NETLINK_RESPONSE, /* Notify thtat Netlink response is available */
+  WORK_NETLINK_RESPONSE, /* Notify that Netlink response is available */
   WORK_CAN_READAHEAD     /* Notify that CAN read-ahead data is available */
 };
 
diff --git a/net/can/can.h b/net/can/can.h
index a727612..2377a0c 100644
--- a/net/can/can.h
+++ b/net/can/can.h
@@ -104,7 +104,7 @@ struct can_conn_s
    */
 
   struct can_poll_s pollinfo[4]; /* FIXME make dynamic */
-  
+
 #ifdef CONFIG_NET_CANPROTO_OPTIONS
   int32_t loopback;
   int32_t recv_own_msgs;
@@ -115,12 +115,10 @@ struct can_conn_s
   int32_t tx_deadline;
 # endif
 #endif
-  
+
 #ifdef CONFIG_NET_TIMESTAMP
   FAR struct socket *psock; /* Needed to get SO_TIMESTAMP value */
 #endif
-
-  
 };
 
 /****************************************************************************
@@ -169,8 +167,8 @@ FAR struct can_conn_s *can_alloc(void);
  * Name: can_free()
  *
  * Description:
- *   Free a NetLink connection structure that is no longer in use. This should
- *   be done by the implementation of close().
+ *   Free a NetLink connection structure that is no longer in use. This
+ *   should be done by the implementation of close().
  *
  ****************************************************************************/
 
@@ -259,7 +257,6 @@ uint16_t can_datahandler(FAR struct can_conn_s *conn, FAR uint8_t *buffer,
  *
  ****************************************************************************/
 
-
 ssize_t can_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
                      int flags, FAR struct sockaddr *from,
                      FAR socklen_t *fromlen);
@@ -282,7 +279,7 @@ ssize_t can_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
  *   flags    Receive flags (ignored)
  *
  ****************************************************************************/
-#ifdef CONFIG_NET_RECVMSG_CMSG
+#ifdef CONFIG_NET_CMSG
 ssize_t can_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg,
                     size_t len, int flags);
 #endif
diff --git a/net/can/can_recvfrom.c b/net/can/can_recvfrom.c
index d9ed8cb..b304977 100644
--- a/net/can/can_recvfrom.c
+++ b/net/can/can_recvfrom.c
@@ -50,14 +50,13 @@
 #include <sys/time.h>
 #endif
 
-
 /****************************************************************************
  * Private Types
  ****************************************************************************/
 
 struct can_recvfrom_s
 {
-  FAR struct socket       *pr_sock;      /* The parent socket structure */
+  FAR struct socket *pr_sock;          /* The parent socket structure */
   FAR struct devif_callback_s *pr_cb;  /* Reference to callback instance */
   sem_t        pr_sem;                 /* Semaphore signals recv completion */
   size_t       pr_buflen;              /* Length of receive buffer */
@@ -233,14 +232,15 @@ static inline void can_newdata(FAR struct net_driver_s *dev,
 
 static inline int can_readahead(struct can_recvfrom_s *pstate)
 {
-  FAR struct can_conn_s *conn = (FAR struct can_conn_s *)pstate->pr_sock->s_conn;
+  FAR struct can_conn_s *conn =
+    (FAR struct can_conn_s *) pstate->pr_sock->s_conn;
   FAR struct iob_s *iob;
   int recvlen;
 
   /* Check there is any CAN data already buffered in a read-ahead
    * buffer.
    */
-  
+
   pstate->pr_recvlen = -1;
 
   if ((iob = iob_peek_queue(&conn->readahead)) != NULL &&
@@ -287,15 +287,16 @@ static inline int can_readahead(struct can_recvfrom_s *pstate)
                              IOBUSER_NET_CAN_READAHEAD);
         }
 
-	  /* do not pass frames with DLC > 8 to a legacy socket */
-	  if (!conn->fd_frames)
-	    {
-		  struct canfd_frame *cfd = (struct canfd_frame *)pstate->pr_buffer;
-		  if (cfd->len > CAN_MAX_DLEN)
-		    {
-	  			return 0;
-		    }
-	    }
+      /* do not pass frames with DLC > 8 to a legacy socket */
+
+      if (!conn->fd_frames)
+        {
+          struct canfd_frame *cfd = (struct canfd_frame *)pstate->pr_buffer;
+          if (cfd->len > CAN_MAX_DLEN)
+            {
+              return 0;
+            }
+        }
 
       return recvlen;
     }
@@ -319,13 +320,14 @@ static inline int can_readahead(struct can_recvfrom_s *pstate)
  *   The network is locked.
  *
  ****************************************************************************/
+
 #ifdef CONFIG_NET_TIMESTAMP
-static inline int can_readahead_timestamp(struct can_conn_s *conn, FAR uint8_t *buffer)
+static inline int can_readahead_timestamp(struct can_conn_s *conn,
+                                          FAR uint8_t *buffer)
 {
   FAR struct iob_s *iob;
   int recvlen;
 
-
   if ((iob = iob_peek_queue(&conn->readahead)) != NULL)
     {
       DEBUGASSERT(iob->io_pktlen > 0);
@@ -379,26 +381,27 @@ static inline int can_readahead_timestamp(struct can_conn_s *conn, FAR uint8_t *
 #ifdef CONFIG_NET_CANPROTO_OPTIONS
 static int can_recv_filter(struct can_conn_s *conn, canid_t id)
 {
-  for(int i = 0; i < conn->filter_count; i++)
+  for (int i = 0; i < conn->filter_count; i++)
     {
-	  if (conn->filters[i].can_id & CAN_INV_FILTER)
-	    {
-		  if((id & conn->filters[i].can_mask) !=
-				  ((conn->filters[i].can_id & ~CAN_INV_FILTER)
-						  & conn->filters[i].can_mask))
-		    {
-			  return 1;
-		    }
-	    }
-	  else
-	    {
-		  if((id & conn->filters[i].can_mask) ==
-				  (conn->filters[i].can_id & conn->filters[i].can_mask))
-		    {
-			  return 1;
-		    }
-	    }
+      if (conn->filters[i].can_id & CAN_INV_FILTER)
+        {
+          if ((id & conn->filters[i].can_mask) !=
+                ((conn->filters[i].can_id & ~CAN_INV_FILTER) &
+                conn->filters[i].can_mask))
+            {
+              return 1;
+            }
+        }
+      else
+        {
+          if ((id & conn->filters[i].can_mask) ==
+                (conn->filters[i].can_id & conn->filters[i].can_mask))
+            {
+              return 1;
+            }
+        }
     }
+
   return 0;
 }
 #endif
@@ -416,46 +419,50 @@ static uint16_t can_recvfrom_eventhandler(FAR struct net_driver_s *dev,
     {
       if ((flags & CAN_NEWDATA) != 0)
         {
-    	  /* If a new packet is available, check receive filters
-    	   * when is valid then complete the read action. */
+          /* If a new packet is available, check receive filters
+           * when is valid then complete the read action.
+           */
 #ifdef CONFIG_NET_CANPROTO_OPTIONS
-    	  if(can_recv_filter(conn,(canid_t)*dev->d_appdata) == 0)
-    	    {
-    		  flags &= ~CAN_NEWDATA;
-    	  	  return flags;
-    		}
+          if (can_recv_filter(conn, (canid_t) *dev->d_appdata) == 0)
+            {
+              flags &= ~CAN_NEWDATA;
+              return flags;
+            }
 #endif
 
-    	  /* do not pass frames with DLC > 8 to a legacy socket */
-    	  if (!conn->fd_frames)
-    	    {
-    		  struct canfd_frame *cfd = (struct canfd_frame*)dev->d_appdata;
-    	      if (cfd->len > CAN_MAX_DLEN)
-    	      {
-    	    	/* DO WE NEED TO CLEAR FLAGS?? */
-    	        flags &= ~CAN_NEWDATA;
-  	  			return flags;
-    	      }
-    	    }
+          /* do not pass frames with DLC > 8 to a legacy socket */
+
+          if (!conn->fd_frames)
+            {
+              struct canfd_frame *cfd = (struct canfd_frame *)dev->d_appdata;
+              if (cfd->len > CAN_MAX_DLEN)
+                {
+                  /* DO WE NEED TO CLEAR FLAGS?? */
+
+                  flags &= ~CAN_NEWDATA;
+                  return flags;
+                }
+            }
 
           /* Copy the packet */
 
           can_newdata(dev, pstate);
 
 #ifdef CONFIG_NET_TIMESTAMP
-		  if(pstate->pr_sock->s_timestamp)
-			{
-			  if(pstate->pr_msglen == sizeof(struct timeval))
-			    {
-				  can_readahead_timestamp(conn, pstate->pr_msgbuf);
-			    }
-			  else
-			    {
-				/* We still have to consume the data otherwise IOB gets full */
-				  uint8_t dummy_buf[sizeof(struct timeval)];
-				  can_readahead_timestamp(conn, &dummy_buf);
-			    }
-			}
+          if (pstate->pr_sock->s_timestamp)
+            {
+              if (pstate->pr_msglen == sizeof(struct timeval))
+                {
+                  can_readahead_timestamp(conn, pstate->pr_msgbuf);
+                }
+              else
+                {
+                  /* We still have to consume the data otherwise IOB gets full */
+
+                  uint8_t dummy_buf[sizeof(struct timeval)];
+                  can_readahead_timestamp(conn, &dummy_buf);
+                }
+            }
 #endif
 
           /* We are finished. */
@@ -508,6 +515,7 @@ static ssize_t can_recvfrom_result(int result,
   if (pstate->pr_result < 0)
     {
       /* This might return EAGAIN on a timeout */
+
       return pstate->pr_result;
     }
 
@@ -592,10 +600,10 @@ ssize_t can_recvfrom(FAR struct socket *psock, FAR void *buf,
 
   ret = can_readahead(&state);
   if (ret > 0)
-    {      
+    {
       goto errout_with_state;
     }
-    
+
   ret = state.pr_recvlen;
 
   /* Handle non-blocking CAN sockets */
@@ -610,7 +618,7 @@ ssize_t can_recvfrom(FAR struct socket *psock, FAR void *buf,
         {
           /* Nothing was received */
 
-          ret = -EAGAIN;          
+          ret = -EAGAIN;
           goto errout_with_state;
         }
     }
@@ -675,7 +683,8 @@ errout_with_state:
  *   flags    Receive flags (ignored)
  *
  ****************************************************************************/
-#ifdef CONFIG_NET_RECVMSG_CMSG
+
+#ifdef CONFIG_NET_CMSG
 ssize_t can_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg,
                     size_t len, int flags)
 {
@@ -707,20 +716,22 @@ ssize_t can_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg,
   nxsem_init(&state.pr_sem, 0, 0); /* Doesn't really fail */
   nxsem_setprotocol(&state.pr_sem, SEM_PRIO_NONE);
 
-
   state.pr_buflen = msg->msg_iov->iov_len;
   state.pr_buffer = msg->msg_iov->iov_base;
+
 #ifdef CONFIG_NET_TIMESTAMP
-  if(psock->s_timestamp && msg->msg_controllen == (sizeof(struct cmsghdr) + sizeof(struct timeval)))
+  if (psock->s_timestamp && msg->msg_controllen ==
+        (sizeof(struct cmsghdr) + sizeof(struct timeval)))
     {
-	  struct cmsghdr* cmsg = CMSG_FIRSTHDR(msg);
-	  state.pr_msglen = sizeof(struct timeval);
-	  state.pr_msgbuf = CMSG_DATA(cmsg);
-	  cmsg->cmsg_level = SOL_SOCKET;
-	  cmsg->cmsg_type = SO_TIMESTAMP;
-	  cmsg->cmsg_len = state.pr_msglen;
+      struct cmsghdr *cmsg = CMSG_FIRSTHDR(msg);
+      state.pr_msglen = sizeof(struct timeval);
+      state.pr_msgbuf = CMSG_DATA(cmsg);
+      cmsg->cmsg_level = SOL_SOCKET;
+      cmsg->cmsg_type = SO_TIMESTAMP;
+      cmsg->cmsg_len = state.pr_msglen;
     }
 #endif
+
   state.pr_sock   = psock;
 
   /* Handle any any CAN data already buffered in a read-ahead buffer.  NOTE
@@ -732,20 +743,22 @@ ssize_t can_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg,
   if (ret > 0)
     {
 #ifdef CONFIG_NET_TIMESTAMP
-	  if(psock->s_timestamp)
-	    {
-		  if(state.pr_msglen == sizeof(struct timeval))
-		    {
-			  can_readahead_timestamp(conn, state.pr_msgbuf);
-		    }
-		  else
-		    {
-			/* We still have to consume the data otherwise IOB gets full */
-		    uint8_t dummy_buf[sizeof(struct timeval)];
-			can_readahead_timestamp(conn, &dummy_buf);
-		    }
-	    }
+      if (psock->s_timestamp)
+        {
+          if (state.pr_msglen == sizeof(struct timeval))
+            {
+              can_readahead_timestamp(conn, state.pr_msgbuf);
+            }
+          else
+            {
+              /* We still have to consume the data otherwise IOB gets full */
+
+              uint8_t dummy_buf[sizeof(struct timeval)];
+              can_readahead_timestamp(conn, &dummy_buf);
+            }
+        }
 #endif
+
       goto errout_with_state;
     }
 


[incubator-nuttx] 12/31: Fixed SocketCAN IOB default config and IOB typos

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch SocketCAN
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit cd174476351be9dae269ce60468b548b77a33863
Author: Peter van der Perk <pe...@nxp.com>
AuthorDate: Thu Mar 5 09:49:41 2020 +0100

    Fixed SocketCAN IOB default config and IOB typos
---
 net/can/Kconfig        | 2 ++
 net/can/can_callback.c | 2 +-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/net/can/Kconfig b/net/can/Kconfig
index 2272db7..d5b6dbd 100644
--- a/net/can/Kconfig
+++ b/net/can/Kconfig
@@ -8,6 +8,8 @@ menu "SocketCAN Support"
 config NET_CAN
 	bool "SocketCAN support"
 	default n
+	select NET_READAHEAD
+	depends on NET
 	---help---
 		Enable support for SocketCAN sockets that will permit.
 
diff --git a/net/can/can_callback.c b/net/can/can_callback.c
index 0f60b6a..7b923d3 100644
--- a/net/can/can_callback.c
+++ b/net/can/can_callback.c
@@ -196,7 +196,7 @@ uint16_t can_datahandler(FAR struct can_conn_s *conn, FAR uint8_t *buffer,
   if (ret < 0)
     {
       nerr("ERROR: Failed to queue the I/O buffer chain: %d\n", ret);
-      iob_free_chain(iob, IOBUSER_NET_TCP_READAHEAD);
+      iob_free_chain(iob, IOBUSER_NET_CAN_READAHEAD);
       return 0;
     }
 


[incubator-nuttx] 16/31: SocketCAN added protocol 0 to suport netlib_ifup with NET_PKT disabled

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch SocketCAN
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 932daacce02503a090a348531179eea3eceb73da
Author: Peter van der Perk <pe...@nxp.com>
AuthorDate: Mon Mar 9 13:49:11 2020 +0100

    SocketCAN added protocol 0 to suport netlib_ifup with NET_PKT disabled
---
 net/can/can_sockif.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/net/can/can_sockif.c b/net/can/can_sockif.c
index 573ddd8..4deef14 100644
--- a/net/can/can_sockif.c
+++ b/net/can/can_sockif.c
@@ -199,6 +199,7 @@ static int can_setup(FAR struct socket *psock, int protocol)
 
   switch (protocol)
     {
+      case 0:            /* INET subsystem for netlib_ifup */
       case CAN_RAW:      /* RAW sockets */
       case CAN_BCM:      /* Broadcast Manager */
       case CAN_TP16:     /* VAG Transport Protocol v1.6 */


[incubator-nuttx] 08/31: PR350 Coding Standard Corrections

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch SocketCAN
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 5909e58ea5f5aec810829e3f05cb9fa0819676bd
Author: Gregory Nutt <gn...@nuttx.org>
AuthorDate: Fri Feb 21 11:17:10 2020 -0600

    PR350 Coding Standard Corrections
    
    Run all .c and .h files in PR350 through tools/nxstyle and correct all (relevant) errors reported by the tool.  Somes files like arch/arm/src/s32k1xx/s32k1xx_flexcan.c did not following the coding standard and received substantial modification.
    
    Nothing may enter the NuttX repositories that does not conform to the coding standard!  See https://cwiki.apache.org/confluence/display/NUTTX/Coding+Standard
---
 arch/arm/src/s32k1xx/s32k1xx_flexcan.c | 1027 ++++++++++++++++----------------
 include/netpacket/can.h                |   10 +-
 include/nuttx/can.h                    |  150 ++---
 include/nuttx/mm/iob.h                 |    1 +
 include/sys/socket.h                   |    8 +-
 net/can/can.h                          |   14 +-
 net/can/can_callback.c                 |   80 +--
 net/can/can_getsockopt.c               |   73 +--
 net/can/can_input.c                    |   50 +-
 net/can/can_poll.c                     |   47 +-
 net/can/can_recvfrom.c                 |   88 ++-
 net/can/can_setsockopt.c               |   70 +--
 net/can/can_sockif.c                   |  135 +++--
 net/socket/getsockopt.c                |    2 +-
 14 files changed, 829 insertions(+), 926 deletions(-)

diff --git a/arch/arm/src/s32k1xx/s32k1xx_flexcan.c b/arch/arm/src/s32k1xx/s32k1xx_flexcan.c
index 9c7a7d7..50a5c18 100644
--- a/arch/arm/src/s32k1xx/s32k1xx_flexcan.c
+++ b/arch/arm/src/s32k1xx/s32k1xx_flexcan.c
@@ -1,35 +1,20 @@
 /****************************************************************************
  * arch/arm/src/s32k1xx/s32k1xx_flexcan.c
  *
- *   Copyright (C) 2019 Gregory Nutt. All rights reserved.
- *   Authors: Gregory Nutt <gn...@nuttx.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- *    used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
  *
  ****************************************************************************/
 
@@ -102,7 +87,8 @@
 /* CONFIG_S32K1XX_FLEXCAN_NETHIFS determines the number of physical interfaces
  * that will be supported.
  */
-/*
+
+#if 0
 #if CONFIG_S32K1XX_FLEXCAN_NETHIFS != 1
 #  error "CONFIG_S32K1XX_FLEXCAN_NETHIFS must be one for now"
 #endif
@@ -113,20 +99,22 @@
 
 #if CONFIG_S32K1XX_FLEXCAN_NRXBUFFERS < 1
 #  error "Need at least one RX buffer"
-#endif*/
+#endif
+#endif
+
+#define MASKSTDID                   0x000007ff
+#define MASKEXTID                   0x1fffffff
+#define FLAGEFF                     (1 << 31) /* Extended frame format */
+#define FLAGRTR                     (1 << 30) /* Remote transmission request */
 
-#define MaskStdID                   0x000007FF
-#define MaskExtID                   0x1FFFFFFF
-#define FlagEFF                     (1 << 31) /* Extended frame format */
-#define FlagRTR                     (1 << 30) /* Remote transmission request */
+/* Fixme nice variables/constants */
 
-//Fixme nice variables/constants
-#define RxMBCount                   6
-#define FilterCount                 0
-#define RxandFilterMBCount          (RxMBCount + FilterCount)
-#define TxMBCount                   12 //???????????? why 12 idk it works
-#define TotalMBcount                RxandFilterMBCount + TxMBCount
-#define TXMBMask                    (((1 << TxMBCount)-1) << RxandFilterMBCount)
+#define RXMBCOUNT                   6
+#define FILTERCOUNT                 0
+#define RXANDFILTERMBCOUNT          (RXMBCOUNT + FILTERCOUNT)
+#define TXMBCOUNT                   12 //???????????? why 12 idk it works
+#define TOTALMBCOUNT                RXANDFILTERMBCOUNT + TXMBCOUNT
+#define TXMBMASK                    (((1 << TXMBCOUNT)-1) << RXANDFILTERMBCOUNT)
 
 #define CAN_FIFO_NE                 (1 << 5)
 #define CAN_FIFO_OV                 (1 << 6)
@@ -135,9 +123,6 @@
 
 static int peak_tx_mailbox_index_ = 0;
 
-
-
-
 /* Normally you would clean the cache after writing new values to the DMA
  * memory so assure that the dirty cache lines are flushed to memory
  * before the DMA occurs.  And you would invalid the cache after a data is
@@ -208,82 +193,81 @@ static int peak_tx_mailbox_index_ = 0;
  * Private Types
  ****************************************************************************/
 
-
-union TXcsType
+union txcs_e
 {
-	volatile uint32_t w;
-	struct
-	{
-		volatile uint32_t time_stamp : 16;
-		volatile uint32_t dlc : 4;
-		volatile uint32_t rtr : 1;
-		volatile uint32_t ide : 1;
-		volatile uint32_t srr : 1;
-		volatile uint32_t res : 1;
-		volatile uint32_t code : 4;
-		volatile uint32_t res2 : 4;
-	};
+  volatile uint32_t w;
+  struct
+  {
+    volatile uint32_t time_stamp : 16;
+    volatile uint32_t dlc : 4;
+    volatile uint32_t rtr : 1;
+    volatile uint32_t ide : 1;
+    volatile uint32_t srr : 1;
+    volatile uint32_t res : 1;
+    volatile uint32_t code : 4;
+    volatile uint32_t res2 : 4;
+  };
 };
 
-union RXcsType
+union rxcs_e
 {
-	volatile uint32_t cs;
-	struct
-	{
-		volatile uint32_t time_stamp : 16;
-		volatile uint32_t dlc : 4;
-		volatile uint32_t rtr : 1;
-		volatile uint32_t ide : 1;
-		volatile uint32_t srr : 1;
-		volatile uint32_t res : 9;
-	};
+  volatile uint32_t cs;
+  struct
+  {
+    volatile uint32_t time_stamp : 16;
+    volatile uint32_t dlc : 4;
+    volatile uint32_t rtr : 1;
+    volatile uint32_t ide : 1;
+    volatile uint32_t srr : 1;
+    volatile uint32_t res : 9;
+  };
 };
 
-union IDType
+union id_e
 {
-	volatile uint32_t w;
-	struct
-	{
-		volatile uint32_t ext : 29;
-		volatile uint32_t resex : 3;
-	};
-	struct
-	{
-		volatile uint32_t res : 18;
-		volatile uint32_t std : 11;
-		volatile uint32_t resstd : 3;
-	};
+  volatile uint32_t w;
+  struct
+  {
+    volatile uint32_t ext : 29;
+    volatile uint32_t resex : 3;
+  };
+  struct
+  {
+    volatile uint32_t res : 18;
+    volatile uint32_t std : 11;
+    volatile uint32_t resstd : 3;
+  };
 };
 
-union DataType
+union data_e
 {
-	volatile uint32_t l;
-	volatile uint32_t h;
-	struct
-	{
-		volatile uint32_t b3 : 8;
-		volatile uint32_t b2 : 8;
-		volatile uint32_t b1 : 8;
-		volatile uint32_t b0 : 8;
-		volatile uint32_t b7 : 8;
-		volatile uint32_t b6 : 8;
-		volatile uint32_t b5 : 8;
-		volatile uint32_t b4 : 8;
-	};
+  volatile uint32_t l;
+  volatile uint32_t h;
+  struct
+  {
+    volatile uint32_t b3 : 8;
+    volatile uint32_t b2 : 8;
+    volatile uint32_t b1 : 8;
+    volatile uint32_t b0 : 8;
+    volatile uint32_t b7 : 8;
+    volatile uint32_t b6 : 8;
+    volatile uint32_t b5 : 8;
+    volatile uint32_t b4 : 8;
+  };
 };
 
-struct MbTx
+struct mbtx_s
 {
-	union TXcsType CS;
-	union IDType ID;
-	union DataType data;
+  union txcs_e cs;
+  union id_e id;
+  union data_e data;
 };
 
-struct MbRx
+struct mbrx_s
 {
-	union RXcsType CS;
-	union IDType ID;
-	union DataType data;
+  union rxcs_e cs;
+  union id_e id;
+  union data_e data;
 };
 
 /* The s32k1xx_driver_s encapsulates all state information for a single
@@ -308,12 +292,10 @@ struct s32k1xx_driver_s
 
   struct net_driver_s dev;     /* Interface understood by the network */
 
-  struct MbRx *rx;
-  struct MbTx *tx;
-
+  struct mbrx_s *rx;
+  struct mbtx_s *tx;
 };
 
-
 /****************************************************************************
  * Private Data
  ****************************************************************************/
@@ -323,7 +305,6 @@ static struct s32k1xx_driver_s g_flexcan[CONFIG_S32K1XX_ENET_NETHIFS];
 static uint8_t g_desc_pool[2000]
                __attribute__((aligned(ARMV7M_DCACHE_LINESIZE)));
 
-
 /****************************************************************************
  * Private Function Prototypes
  ****************************************************************************/
@@ -350,10 +331,11 @@ static int  s32k1xx_transmit(FAR struct s32k1xx_driver_s *priv);
 static int  s32k1xx_txpoll(struct net_driver_s *dev);
 
 /* Helper functions */
+
 static void s32k1xx_setenable(uint32_t enable);
 static void s32k1xx_setfreeze(uint32_t freeze);
 static uint32_t s32k1xx_waitmcr_change(uint32_t mask,
-		                             uint32_t target_state);
+                                       uint32_t target_state);
 
 /* Interrupt handling */
 
@@ -363,7 +345,7 @@ static void s32k1xx_txdone(FAR struct s32k1xx_driver_s *priv);
 
 static void s32k1xx_flexcan_interrupt_work(FAR void *arg);
 static int  s32k1xx_flexcan_interrupt(int irq, FAR void *context,
-                                   FAR void *arg);
+                                      FAR void *arg);
 
 /* Watchdog timer expirations */
 
@@ -383,13 +365,13 @@ static int  s32k1xx_txavail(struct net_driver_s *dev);
 
 #ifdef CONFIG_NET_MCASTGROUP
 static int  s32k1xx_addmac(struct net_driver_s *dev,
-              FAR const uint8_t *mac);
+                           FAR const uint8_t *mac);
 static int  s32k1xx_rmmac(struct net_driver_s *dev, FAR const uint8_t *mac);
 #endif
 
 #ifdef CONFIG_NETDEV_IOCTL
 static int  s32k1xx_ioctl(struct net_driver_s *dev, int cmd,
-            unsigned long arg);
+                          unsigned long arg);
 #endif
 
 /* Initialization */
@@ -402,7 +384,6 @@ static void s32k1xx_reset(struct s32k1xx_driver_s *priv);
  * Private Functions
  ****************************************************************************/
 
-
 /****************************************************************************
  * Function: s32k1xx_txringfull
  *
@@ -428,7 +409,7 @@ static bool s32k1xx_txringfull(FAR struct s32k1xx_driver_s *priv)
    */
 
   txnext = priv->txhead + 1;
-  
+
   return priv->txtail == txnext;
 }
 
@@ -452,69 +433,79 @@ static bool s32k1xx_txringfull(FAR struct s32k1xx_driver_s *priv)
  *
  ****************************************************************************/
 
-
 static int s32k1xx_transmit(FAR struct s32k1xx_driver_s *priv)
 {
   #warning Missing logic
 
-  struct can_frame *frame = (struct can_frame*)priv->dev.d_buf;
+  struct can_frame *frame = (struct can_frame *)priv->dev.d_buf;
 
-  /*ninfo("CAN id: %i dlc: %i", frame->can_id, frame->can_dlc);
+#if 0
+  ninfo("CAN id: %i dlc: %i", frame->can_id, frame->can_dlc);
 
-  for(int i = 0; i < frame->can_dlc; i++){
-	  ninfo(" %02X", frame->data[i]);
-  }
-  ninfo("\r\n");*/
+  for (int i = 0; i < frame->can_dlc; i++)
+    {
+      ninfo(" %02X", frame->data[i]);
+    }
+
+  ninfo("\r\n");
+#endif
 
   /* Attempt to write frame */
+
   uint32_t mbi = 0;
-  if ((getreg32(S32K1XX_CAN0_ESR2) & (CAN_ESR2_IMB | CAN_ESR2_VPS)) == (CAN_ESR2_IMB | CAN_ESR2_VPS))
-  {
-	  mbi = (getreg32(S32K1XX_CAN0_ESR2) & CAN_ESR2_LPTM_MASK) >> CAN_ESR2_LPTM_SHIFT;
-  }
+  if ((getreg32(S32K1XX_CAN0_ESR2) & (CAN_ESR2_IMB | CAN_ESR2_VPS)) ==
+      (CAN_ESR2_IMB | CAN_ESR2_VPS))
+    {
+      mbi = (getreg32(S32K1XX_CAN0_ESR2) & CAN_ESR2_LPTM_MASK) >>
+            CAN_ESR2_LPTM_SHIFT;
+    }
 
-  uint32_t mb_bit = 1 << (RxandFilterMBCount + mbi);
+  uint32_t mb_bit = 1 << (RXANDFILTERMBCOUNT + mbi);
 
-  while (mbi < TxMBCount)
-  {
+  while (mbi < TXMBCOUNT)
+    {
+      if (priv->tx[mbi].cs.code != CAN_TXMB_DATAORREMOTE)
+        {
+          putreg32(mb_bit, S32K1XX_CAN0_IFLAG1);
+          break;
+        }
 
-	  if (priv->tx[mbi].CS.code != CAN_TXMB_DATAORREMOTE)
-	  {
-		  putreg32(mb_bit, S32K1XX_CAN0_IFLAG1);
-		  break;
-	  }
-	  mb_bit <<= 1;
-	  mbi++;
-  }
+      mb_bit <<= 1;
+      mbi++;
+    }
 
-  if ((mbi-RxandFilterMBCount) == TxMBCount)
-  {
-	  nwarn("No TX MB available mbi %i\r\n", mbi);
-	  return 0;       // No transmission for you!
-  }
+  if ((mbi - RXANDFILTERMBCOUNT) == TXMBCOUNT)
+    {
+      nwarn("No TX MB available mbi %i\r\n", mbi);
+      return 0;       /* No transmission for you! */
+    }
 
-  peak_tx_mailbox_index_ = (peak_tx_mailbox_index_ > mbi ? peak_tx_mailbox_index_ : mbi );
+  peak_tx_mailbox_index_ =
+    (peak_tx_mailbox_index_ > mbi ? peak_tx_mailbox_index_ : mbi);
 
-  union TXcsType cs;
+  union txcs_e cs;
   cs.code = CAN_TXMB_DATAORREMOTE;
-  struct MbTx* mb = &priv->tx[mbi];
-  mb->CS.code = CAN_TXMB_INACTIVE;
+  struct mbtx_s *mb = &priv->tx[mbi];
+  mb->cs.code = CAN_TXMB_INACTIVE;
 
-  if (0) //FIXME detect Std or Ext id
-  {
-	  cs.ide = 1;
-	  mb->ID.ext = frame->can_id & MaskExtID;
-  }
+  if (0) /* FIXME detect Std or Ext id */
+    {
+      cs.ide = 1;
+      mb->id.ext = frame->can_id & MASKEXTID;
+    }
   else
-  {
-	  mb->ID.std = frame->can_id & MaskStdID;
-  }
+    {
+      mb->id.std = frame->can_id & MASKSTDID;
+    }
 
-  //cs.rtr = frame.isRemoteTransmissionRequest();
+#if 0
+  cs.rtr = frame.isRemoteTransmissionRequest();
+#endif
 
   cs.dlc = frame->can_dlc;
 
-  //FIXME endian swap instruction or somekind takes 1.5us right now
+  /* FIXME endian swap instruction or somekind takes 1.5us right now */
+
   mb->data.b0 = frame->data[0];
   mb->data.b1 = frame->data[1];
   mb->data.b2 = frame->data[2];
@@ -524,20 +515,22 @@ static int s32k1xx_transmit(FAR struct s32k1xx_driver_s *priv)
   mb->data.b6 = frame->data[6];
   mb->data.b7 = frame->data[7];
 
-  /*
-   * Registering the pending transmission so we can track its deadline and loopback it as needed
+#if 0
+  /* Registering the pending transmission so we can track its deadline and
+   * loopback it as needed
    */
-  /*TxItem& txi = pending_tx_[mbi];
+
+  txitem& txi        = pending_tx_[mbi];
   txi.deadline       = tx_deadline;
   txi.frame          = frame;
   txi.loopback       = (flags & uavcan::CanIOFlagLoopback) != 0;
   txi.abort_on_error = (flags & uavcan::CanIOFlagAbortOnError) != 0;
-  txi.pending        = TxItem::busy;*/
-
+  txi.pending        = txitem::busy;
+#endif
 
   s32k1xx_gpiowrite(PIN_PORTD | PIN31, 0);
 
-  mb->CS = cs; // Go.
+  mb->cs = cs; /* Go. */
 
   uint32_t regval;
   regval = getreg32(S32K1XX_CAN0_IMASK1);
@@ -585,14 +578,15 @@ static int s32k1xx_txpoll(struct net_driver_s *dev)
 
   if (priv->dev.d_len > 0)
     {
-
       if (!devif_loopback(&priv->dev))
         {
           /* Send the packet */
 
           s32k1xx_transmit(priv);
-          /*priv->dev.d_buf =
-            (uint8_t *)s32k1xx_swap32((uint32_t)priv->txdesc[priv->txhead].data);*/
+#if 0
+          priv->dev.d_buf =
+            (uint8_t *)s32k1xx_swap32((uint32_t)priv->txdesc[priv->txhead].data);
+#endif
 
           /* Check if there is room in the device to hold another packet. If
            * not, return a non-zero value to terminate the poll.
@@ -632,7 +626,6 @@ static int s32k1xx_txpoll(struct net_driver_s *dev)
 
 static inline void s32k1xx_dispatch(FAR struct s32k1xx_driver_s *priv)
 {
-    
   #warning Missing logic
 }
 
@@ -656,96 +649,90 @@ static inline void s32k1xx_dispatch(FAR struct s32k1xx_driver_s *priv)
 static void s32k1xx_receive(FAR struct s32k1xx_driver_s *priv)
 {
   #warning Missing logic
-	//ninfo("FLEXCAN: receive\r\n");
-
-	s32k1xx_gpiowrite(PIN_PORTD | PIN31, 1);
-
-	struct can_frame frame;
-	uint32_t flags = getreg32(S32K1XX_CAN0_IFLAG1);
-
-	if ((flags & FIFO_IFLAG1) == 0)
-	{
-		// Weird, IRQ is here but no data to read
-		return;
-	}
+  s32k1xx_gpiowrite(PIN_PORTD | PIN31, 1);
 
-	if (flags & CAN_FIFO_OV)
-	{
-		//error_cnt_++;
-		putreg32(CAN_FIFO_OV, S32K1XX_CAN0_IFLAG1);
-	}
+  struct can_frame frame;
+  uint32_t flags = getreg32(S32K1XX_CAN0_IFLAG1);
 
-	if (flags & CAN_FIFO_WARN)
-	{
-		//fifo_warn_cnt_++;
-		putreg32(CAN_FIFO_WARN, S32K1XX_CAN0_IFLAG1);
-	}
-
-	if (flags & CAN_FIFO_NE)
-	{
-		struct MbRx *rf = priv->rx;
+  if ((flags & FIFO_IFLAG1) == 0)
+    {
+      /* Weird, IRQ is here but no data to read */
 
-		/*
-		 * Read the frame contents
-		 */
+      return;
+    }
 
-		if (rf->CS.ide)
-		{
-			frame.can_id = MaskExtID & rf->ID.ext;
-			frame.can_id |= FlagEFF;
-		}
-		else
-		{
-			frame.can_id = MaskStdID & rf->ID.std;
-		}
+  if (flags & CAN_FIFO_OV)
+    {
+#if 0
+      error_cnt_++;
+#endif
+      putreg32(CAN_FIFO_OV, S32K1XX_CAN0_IFLAG1);
+    }
 
-		if (rf->CS.rtr)
-		{
-			frame.can_id |= FlagRTR;
-		}
+  if (flags & CAN_FIFO_WARN)
+    {
+#if 0
+      fifo_warn_cnt_++;
+#endif
+      putreg32(CAN_FIFO_WARN, S32K1XX_CAN0_IFLAG1);
+    }
 
-		frame.can_dlc = rf->CS.dlc;
+  if (flags & CAN_FIFO_NE)
+    {
+      struct mbrx_s *rf = priv->rx;
 
-		frame.data[0] = rf->data.b0;
-		frame.data[1] = rf->data.b1;
-		frame.data[2] = rf->data.b2;
-		frame.data[3] = rf->data.b3;
-		frame.data[4] = rf->data.b4;
-		frame.data[5] = rf->data.b5;
-		frame.data[6] = rf->data.b6;
-		frame.data[7] = rf->data.b7;
+      /* Read the frame contents */
 
+      if (rf->cs.ide)
+        {
+          frame.can_id = MASKEXTID & rf->id.ext;
+          frame.can_id |= FLAGEFF;
+        }
+      else
+        {
+          frame.can_id = MASKSTDID & rf->id.std;
+        }
 
-		putreg32(CAN_FIFO_NE, S32K1XX_CAN0_IFLAG1);
+      if (rf->cs.rtr)
+        {
+          frame.can_id |= FLAGRTR;
+        }
 
-		/* Copy the buffer pointer to priv->dev.d_buf.  Set amount of data
-		 * in priv->dev.d_len
-		 */
+      frame.can_dlc = rf->cs.dlc;
 
-		priv->dev.d_len = sizeof(struct can_frame);
-		priv->dev.d_buf =
-				(uint8_t *)s32k1xx_swap32((uint32_t)&frame); //FIXME
+      frame.data[0] = rf->data.b0;
+      frame.data[1] = rf->data.b1;
+      frame.data[2] = rf->data.b2;
+      frame.data[3] = rf->data.b3;
+      frame.data[4] = rf->data.b4;
+      frame.data[5] = rf->data.b5;
+      frame.data[6] = rf->data.b6;
+      frame.data[7] = rf->data.b7;
 
-		/* Invalidate the buffer so that the correct packet will be re-read
-		 * from memory when the packet content is accessed.
-		 */
+      putreg32(CAN_FIFO_NE, S32K1XX_CAN0_IFLAG1);
 
-		up_invalidate_dcache((uintptr_t)priv->dev.d_buf,
-				(uintptr_t)priv->dev.d_buf + priv->dev.d_len);
+      /* Copy the buffer pointer to priv->dev.d_buf.  Set amount of data
+       * in priv->dev.d_len
+       */
 
-		/* Send to socket interface */
-		NETDEV_RXPACKETS(&priv->dev);
+      priv->dev.d_len = sizeof(struct can_frame);
+      priv->dev.d_buf = (uint8_t *)s32k1xx_swap32((uint32_t)&frame); /* FIXME */
 
-		can_input(&priv->dev);
+      /* Invalidate the buffer so that the correct packet will be re-read
+       * from memory when the packet content is accessed.
+       */
 
+      up_invalidate_dcache((uintptr_t)priv->dev.d_buf,
+                      (uintptr_t)priv->dev.d_buf + priv->dev.d_len);
 
+      /* Send to socket interface */
 
+      NETDEV_RXPACKETS(&priv->dev);
 
-		/*
-		 * Store with timeout into the FIFO buffer and signal update event
-		 */
+      can_input(&priv->dev);
 
-	}
+      /* Store with timeout into the FIFO buffer and signal update event */
+    }
 }
 
 /****************************************************************************
@@ -771,24 +758,27 @@ static void s32k1xx_txdone(FAR struct s32k1xx_driver_s *priv)
   #warning Missing logic
 
   uint32_t tx_iflags;
-  tx_iflags = getreg32(S32K1XX_CAN0_IFLAG1) & TXMBMask;
+  tx_iflags = getreg32(S32K1XX_CAN0_IFLAG1) & TXMBMASK;
 
-  //FIXME process aborts
+  /* FIXME process aborts */
 
   /* Process TX completions */
 
-  uint32_t mb_bit = 1 << RxMBCount;
-  for(uint32_t mbi = 0; tx_iflags && mbi < TxMBCount; mbi++)
-  {
+  uint32_t mb_bit = 1 << RXMBCOUNT;
+  for (uint32_t mbi = 0; tx_iflags && mbi < TXMBCOUNT; mbi++)
+    {
       if (tx_iflags & mb_bit)
-      {
-    	  putreg32(mb_bit, S32K1XX_CAN0_IFLAG1);
+        {
+          putreg32(mb_bit, S32K1XX_CAN0_IFLAG1);
           tx_iflags &= ~mb_bit;
-          //const bool txok = priv->tx[mbi].CS.code != CAN_TXMB_ABORT;
-          //handleTxMailboxInterrupt(mbi, txok, utc_usec);
-      }
+#if 0
+          const bool txok = priv->tx[mbi].cs.code != CAN_TXMB_ABORT;
+          handleTxMailboxInterrupt(mbi, txok, utc_usec);
+#endif
+        }
+
       mb_bit <<= 1;
-  }
+    }
 }
 
 /****************************************************************************
@@ -833,27 +823,26 @@ static void s32k1xx_flexcan_interrupt_work(FAR void *arg)
  *
  ****************************************************************************/
 
-
 static int s32k1xx_flexcan_interrupt(int irq, FAR void *context, FAR void *arg)
 {
   #warning Missing logic
-	FAR struct s32k1xx_driver_s *priv = &g_flexcan[0];
-	uint32_t flags;
-	flags  = getreg32(S32K1XX_CAN0_IFLAG1);
-	flags &= FIFO_IFLAG1;
-
-	if(flags)
-	{
-		s32k1xx_receive(priv);
-	}
-
-	flags  = getreg32(S32K1XX_CAN0_IFLAG1);
-	flags &= TXMBMask;
-
-	if(flags)
-	{
-        s32k1xx_txdone(priv);
-	}
+  FAR struct s32k1xx_driver_s *priv = &g_flexcan[0];
+  uint32_t flags;
+  flags  = getreg32(S32K1XX_CAN0_IFLAG1);
+  flags &= FIFO_IFLAG1;
+
+  if (flags)
+    {
+      s32k1xx_receive(priv);
+    }
+
+  flags  = getreg32(S32K1XX_CAN0_IFLAG1);
+  flags &= TXMBMASK;
+
+  if (flags)
+    {
+      s32k1xx_txdone(priv);
+    }
 }
 
 /****************************************************************************
@@ -875,7 +864,7 @@ static int s32k1xx_flexcan_interrupt(int irq, FAR void *context, FAR void *arg)
 static void s32k1xx_txtimeout_work(FAR void *arg)
 {
   #warning Missing logic
-	  ninfo("FLEXCAN: tx timeout work\r\n");
+  ninfo("FLEXCAN: tx timeout work\r\n");
 }
 
 /****************************************************************************
@@ -900,7 +889,7 @@ static void s32k1xx_txtimeout_work(FAR void *arg)
 static void s32k1xx_txtimeout_expiry(int argc, uint32_t arg, ...)
 {
   #warning Missing logic
-	  ninfo("FLEXCAN: tx timeout expiry\r\n");
+  ninfo("FLEXCAN: tx timeout expiry\r\n");
 }
 
 /****************************************************************************
@@ -923,32 +912,29 @@ static void s32k1xx_txtimeout_expiry(int argc, uint32_t arg, ...)
 static void s32k1xx_poll_work(FAR void *arg)
 {
   #warning Missing logic
-	  //ninfo("FLEXCAN: poll work\r\n");
-
-	  FAR struct s32k1xx_driver_s *priv = (FAR struct s32k1xx_driver_s *)arg;
-
-	  /* Check if there is there is a transmission in progress.  We cannot
-	   * perform the TX poll if he are unable to accept another packet for
-	   * transmission.
-	   */
+  FAR struct s32k1xx_driver_s *priv = (FAR struct s32k1xx_driver_s *)arg;
 
-	  net_lock();
-	  if (1) //!s32k1xx_txringfull(priv))
-	    {
-	      /* If so, update TCP timing states and poll the network for new XMIT
-	       * data. Hmmm.. might be bug here.  Does this mean if there is a
-	       * transmit in progress, we will missing TCP time state updates?
-	       */
+  /* Check if there is there is a transmission in progress.  We cannot
+   * perform the TX poll if he are unable to accept another packet for
+   * transmission.
+   */
 
-	      devif_timer(&priv->dev, S32K1XX_WDDELAY, s32k1xx_txpoll);
-	    }
+  net_lock();
+  if (1) /* !s32k1xx_txringfull(priv)) */
+    {
+      /* If so, update TCP timing states and poll the network for new XMIT
+       * data. Hmmm.. might be bug here.  Does this mean if there is a
+       * transmit in progress, we will missing TCP time state updates?
+       */
 
-	  /* Setup the watchdog poll timer again in any case */
+      devif_timer(&priv->dev, S32K1XX_WDDELAY, s32k1xx_txpoll);
+    }
 
-	  wd_start(priv->txpoll, S32K1XX_WDDELAY, s32k1xx_polltimer_expiry,
-	           1, (wdparm_t)priv);
-	  net_unlock();
+  /* Setup the watchdog poll timer again in any case */
 
+  wd_start(priv->txpoll, S32K1XX_WDDELAY, s32k1xx_polltimer_expiry,
+           1, (wdparm_t)priv);
+  net_unlock();
 }
 
 /****************************************************************************
@@ -981,62 +967,67 @@ static void s32k1xx_polltimer_expiry(int argc, uint32_t arg, ...)
 
 static void s32k1xx_setenable(uint32_t enable)
 {
-	uint32_t regval;
-	if(enable)
-	{
-		regval  = getreg32(S32K1XX_CAN0_MCR);
-		regval &= ~(CAN_MCR_MDIS);
-		putreg32(regval, S32K1XX_CAN0_MCR);
-	}
-	else
-	{
-		regval  = getreg32(S32K1XX_CAN0_MCR);
-		regval |= CAN_MCR_MDIS;
-		putreg32(regval, S32K1XX_CAN0_MCR);
-	}
-	s32k1xx_waitmcr_change(CAN_MCR_LPMACK,1);
+  uint32_t regval;
+
+  if (enable)
+    {
+      regval  = getreg32(S32K1XX_CAN0_MCR);
+      regval &= ~(CAN_MCR_MDIS);
+      putreg32(regval, S32K1XX_CAN0_MCR);
+    }
+  else
+    {
+      regval  = getreg32(S32K1XX_CAN0_MCR);
+      regval |= CAN_MCR_MDIS;
+      putreg32(regval, S32K1XX_CAN0_MCR);
+    }
+
+  s32k1xx_waitmcr_change(CAN_MCR_LPMACK, 1);
 }
 
 static void s32k1xx_setfreeze(uint32_t freeze)
 {
-	uint32_t regval;
-	if(freeze)
-	{
-		/* Enter freeze mode */
-		regval  = getreg32(S32K1XX_CAN0_MCR);
-		regval |= (CAN_MCR_HALT | CAN_MCR_FRZ);
-		putreg32(regval, S32K1XX_CAN0_MCR);
-	}
-	else
-	{
-		/* Exit freeze mode */
-		regval  = getreg32(S32K1XX_CAN0_MCR);
-		regval &= ~(CAN_MCR_HALT | CAN_MCR_FRZ);
-		putreg32(regval, S32K1XX_CAN0_MCR);
-	}
+  uint32_t regval;
+  if (freeze)
+    {
+      /* Enter freeze mode */
+
+      regval  = getreg32(S32K1XX_CAN0_MCR);
+      regval |= (CAN_MCR_HALT | CAN_MCR_FRZ);
+      putreg32(regval, S32K1XX_CAN0_MCR);
+    }
+  else
+    {
+      /* Exit freeze mode */
+
+      regval  = getreg32(S32K1XX_CAN0_MCR);
+      regval &= ~(CAN_MCR_HALT | CAN_MCR_FRZ);
+      putreg32(regval, S32K1XX_CAN0_MCR);
+    }
 }
 
 static uint32_t s32k1xx_waitmcr_change(uint32_t mask, uint32_t target_state)
 {
-	const unsigned Timeout = 1000;
-	for (unsigned wait_ack = 0; wait_ack < Timeout; wait_ack++)
-	{
-		const bool state = (getreg32(S32K1XX_CAN0_MCR) & mask) != 0;
-		if (state == target_state)
-		{
-			return true;
-		}
-		up_udelay(10);
-	}
-	return false;
+  const unsigned timeout = 1000;
+  for (unsigned wait_ack = 0; wait_ack < timeout; wait_ack++)
+    {
+      const bool state = (getreg32(S32K1XX_CAN0_MCR) & mask) != 0;
+      if (state == target_state)
+        {
+          return true;
+        }
+
+      up_udelay(10);
+    }
+
+  return false;
 }
 
 static uint32_t s32k1xx_waitfreezeack_change(uint32_t target_state)
 {
-    return s32k1xx_waitmcr_change(CAN_MCR_FRZACK, target_state);
+  return s32k1xx_waitmcr_change(CAN_MCR_FRZACK, target_state);
 }
 
-
 /****************************************************************************
  * Function: s32k1xx_ifup
  *
@@ -1057,16 +1048,16 @@ static uint32_t s32k1xx_waitfreezeack_change(uint32_t target_state)
 static int s32k1xx_ifup(struct net_driver_s *dev)
 {
   FAR struct s32k1xx_driver_s *priv =
-	(FAR struct s32k1xx_driver_s *)dev->d_private;
+    (FAR struct s32k1xx_driver_s *)dev->d_private;
   uint32_t regval;
 
   #warning Missing logic
 
-  if(!s32k1xx_initialize(priv))
-  {
-	  nerr("initialize failed");
-	  return -1;
-  }
+  if (!s32k1xx_initialize(priv))
+    {
+      nerr("initialize failed");
+      return -1;
+    }
 
   /* Set and activate a timer process */
 
@@ -1078,6 +1069,7 @@ static int s32k1xx_ifup(struct net_driver_s *dev)
   priv->dev.d_buf = &g_desc_pool;
 
   /* Set interrupts */
+
   up_enable_irq(S32K1XX_IRQ_CAN0_BUS);
   up_enable_irq(S32K1XX_IRQ_CAN0_ERROR);
   up_enable_irq(S32K1XX_IRQ_CAN0_LPRX);
@@ -1127,28 +1119,28 @@ static int s32k1xx_ifdown(struct net_driver_s *dev)
 
 static void s32k1xx_txavail_work(FAR void *arg)
 {
-	  FAR struct s32k1xx_driver_s *priv = (FAR struct s32k1xx_driver_s *)arg;
+  FAR struct s32k1xx_driver_s *priv = (FAR struct s32k1xx_driver_s *)arg;
 
-	  /* Ignore the notification if the interface is not yet up */
+  /* Ignore the notification if the interface is not yet up */
 
-	  net_lock();
-	  if (priv->bifup)
-	    {
-	      /* Check if there is room in the hardware to hold another outgoing
-	       * packet.
-	       */
+  net_lock();
+  if (priv->bifup)
+    {
+      /* Check if there is room in the hardware to hold another outgoing
+       * packet.
+       */
 
-	      if (!s32k1xx_txringfull(priv))
-	        {
-	          /* No, there is space for another transfer.  Poll the network for
-	           * new XMIT data.
-	           */
+      if (!s32k1xx_txringfull(priv))
+        {
+          /* No, there is space for another transfer.  Poll the network for
+           * new XMIT data.
+           */
 
-	          devif_poll(&priv->dev, s32k1xx_txpoll);
-	        }
-	    }
+          devif_poll(&priv->dev, s32k1xx_txpoll);
+        }
+    }
 
-	  net_unlock();
+  net_unlock();
 }
 
 /****************************************************************************
@@ -1183,8 +1175,9 @@ static int s32k1xx_txavail(struct net_driver_s *dev)
   if (work_available(&priv->pollwork))
     {
       /* Schedule to serialize the poll on the worker thread. */
+
 #ifdef WORK_QUEUE_BYPASS
-	  s32k1xx_txavail_work(priv);
+      s32k1xx_txavail_work(priv);
 #else
       work_queue(ETHWORK, &priv->pollwork, s32k1xx_txavail_work, priv, 0);
 #endif
@@ -1193,7 +1186,6 @@ static int s32k1xx_txavail(struct net_driver_s *dev)
   return OK;
 }
 
-
 /****************************************************************************
  * Function: s32k1xx_ioctl
  *
@@ -1247,119 +1239,131 @@ static int s32k1xx_ioctl(struct net_driver_s *dev, int cmd,
 
 static int s32k1xx_initialize(struct s32k1xx_driver_s *priv)
 {
-	uint32_t regval;
-	uint32_t i;
+  uint32_t regval;
+  uint32_t i;
 
-	/* initialize CAN device */
-	//FIXME we only support a single can device for now
+  /* initialize CAN device */
 
-	//TEST GPIO tming
-	s32k1xx_pinconfig(PIN_PORTD | PIN31 | GPIO_OUTPUT);
+  /* FIXME we only support a single can device for now */
 
+  /* TEST GPIO tming */
 
-	s32k1xx_setenable(0);
+  s32k1xx_pinconfig(PIN_PORTD | PIN31 | GPIO_OUTPUT);
 
-	/* Set SYS_CLOCK src */
-	regval  = getreg32(S32K1XX_CAN0_CTRL1);
-	regval |= CAN_CTRL1_CLKSRC;
-	putreg32(regval, S32K1XX_CAN0_CTRL1);
+  s32k1xx_setenable(0);
 
-	s32k1xx_setenable(1);
+  /* Set SYS_CLOCK src */
 
-	s32k1xx_reset(priv);
+  regval  = getreg32(S32K1XX_CAN0_CTRL1);
+  regval |= CAN_CTRL1_CLKSRC;
+  putreg32(regval, S32K1XX_CAN0_CTRL1);
 
-	/* Enter freeze mode */
-	s32k1xx_setfreeze(1);
-	if(!s32k1xx_waitfreezeack_change(1))
-	{
-		ninfo("FLEXCAN: freeze fail\r\n");
-		return -1;
-	}
+  s32k1xx_setenable(1);
 
-	/*regval  = getreg32(S32K1XX_CAN0_CTRL1);
-	regval |= ((0  << CAN_CTRL1_PRESDIV_SHIFT) & CAN_CTRL1_PRESDIV_MASK)
-					  | ((46 << CAN_CTRL1_ROPSEG_SHIFT) & CAN_CTRL1_ROPSEG_MASK)
-					  | ((18 << CAN_CTRL1_PSEG1_SHIFT) & CAN_CTRL1_PSEG1_MASK)
-					  | ((12 << CAN_CTRL1_PSEG2_SHIFT) & CAN_CTRL1_PSEG2_MASK)
-					  | ((12 << CAN_CTRL1_RJW_SHIFT) & CAN_CTRL1_RJW_MASK)
-					  | CAN_CTRL1_ERRMSK
-					  | CAN_CTRL1_TWRNMSK
-					  | CAN_CTRL1_RWRNMSK;
+  s32k1xx_reset(priv);
 
-	putreg32(regval, S32K1XX_CAN0_CTRL1);*/
+  /* Enter freeze mode */
+
+  s32k1xx_setfreeze(1);
+  if (!s32k1xx_waitfreezeack_change(1))
+    {
+      ninfo("FLEXCAN: freeze fail\r\n");
+      return -1;
+    }
+
+#if 0
+  regval  = getreg32(S32K1XX_CAN0_CTRL1);
+  regval |= ((0  << CAN_CTRL1_PRESDIV_SHIFT) & CAN_CTRL1_PRESDIV_MASK) |
+            ((46 << CAN_CTRL1_ROPSEG_SHIFT) & CAN_CTRL1_ROPSEG_MASK) |
+            ((18 << CAN_CTRL1_PSEG1_SHIFT) & CAN_CTRL1_PSEG1_MASK) |
+            ((12 << CAN_CTRL1_PSEG2_SHIFT) & CAN_CTRL1_PSEG2_MASK) |
+            ((12 << CAN_CTRL1_RJW_SHIFT) & CAN_CTRL1_RJW_MASK) |
+            CAN_CTRL1_ERRMSK |
+            CAN_CTRL1_TWRNMSK |
+            CAN_CTRL1_RWRNMSK;
+
+  putreg32(regval, S32K1XX_CAN0_CTRL1);
+#endif
 
 #define BIT_METHOD2
 #ifdef BIT_METHOD2
-	/* CAN Bit Timing (CBT) configuration for a nominal phase of 1 Mbit/s
-	 * with 80 time quantas,in accordance with Bosch 2012 specification,
-	 * sample point at 83.75% */
-	regval  = getreg32(S32K1XX_CAN0_CBT);
-	regval |= CAN_CBT_BTF |     /* Enable extended bit timing configurations for CAN-FD
-	                                      for setting up separetely nominal and data phase */
-			CAN_CBT_EPRESDIV(0) |  /* Prescaler divisor factor of 1 */
-			CAN_CBT_EPROPSEG(46) | /* Propagation segment of 47 time quantas */
-			CAN_CBT_EPSEG1(18) |   /* Phase buffer segment 1 of 19 time quantas */
-			CAN_CBT_EPSEG2(12) |   /* Phase buffer segment 2 of 13 time quantas */
-			CAN_CBT_ERJW(12);      /* Resynchronization jump width same as PSEG2 */
-	putreg32(regval, S32K1XX_CAN0_CBT);
+  /* CAN Bit Timing (CBT) configuration for a nominal phase of 1 Mbit/s
+   * with 80 time quantas,in accordance with Bosch 2012 specification,
+   * sample point at 83.75%
+   */
+
+  regval  = getreg32(S32K1XX_CAN0_CBT);
+  regval |= CAN_CBT_BTF |          /* Enable extended bit timing configurations
+                                    * for CAN-FD for setting up separately
+                                    * nominal and data phase */
+            CAN_CBT_EPRESDIV(0) |  /* Prescaler divisor factor of 1 */
+            CAN_CBT_EPROPSEG(46) | /* Propagation segment of 47 time quantas */
+            CAN_CBT_EPSEG1(18) |   /* Phase buffer segment 1 of 19 time quantas */
+            CAN_CBT_EPSEG2(12) |   /* Phase buffer segment 2 of 13 time quantas */
+            CAN_CBT_ERJW(12);      /* Resynchronization jump width same as PSEG2 */
+  putreg32(regval, S32K1XX_CAN0_CBT);
 #endif
 
 #ifdef CAN_FD
+  /* Enable CAN FD feature */
+
+  regval  = getreg32(S32K1XX_CAN0_MCR);
+  regval |= CAN_MCR_FDEN;
+  putreg32(regval, S32K1XX_CAN0_MCR);
+
+  /* CAN-FD Bit Timing (FDCBT) for a data phase of 4 Mbit/s with 20 time quantas,
+   * in accordance with Bosch 2012 specification, sample point at 75%
+   */
+
+  regval  = getreg32(S32K1XX_CAN0_FDCBT);
+  regval |= CAN_FDCBT_FPRESDIV(0) | /* Prescaler divisor factor of 1 */
+            CAN_FDCBT_FPROPSEG(7) | /* Propagation semgment of 7 time quantas
+                                     * (only register that doesn't add 1) */
+            CAN_FDCBT_FPSEG1(6) |   /* Phase buffer segment 1 of 7 time quantas */
+            CAN_FDCBT_FPSEG2(4) |   /* Phase buffer segment 2 of 5 time quantas */
+            CAN_FDCBT_FRJW(4);      /* Resynchorinzation jump width same as PSEG2 */
+  putreg32(regval, S32K1XX_CAN0_FDCBT);
+
+  /* Additional CAN-FD configurations */
+
+  regval  = getreg32(S32K1XX_CAN0_FDCTRL);
 
-	/* Enable CAN FD feature */
-	regval  = getreg32(S32K1XX_CAN0_MCR);
-	regval |= CAN_MCR_FDEN;
-	putreg32(regval, S32K1XX_CAN0_MCR);
-
-	/* CAN-FD Bit Timing (FDCBT) for a data phase of 4 Mbit/s with 20 time quantas,
-	                 in accordance with Bosch 2012 specification, sample point at 75% */
-	regval  = getreg32(S32K1XX_CAN0_FDCBT);
-	regval |= CAN_FDCBT_FPRESDIV(0) | /* Prescaler divisor factor of 1 */
-			CAN_FDCBT_FPROPSEG(7) | /* Propagation semgment of 7 time quantas
-	                                                              (only register that doesn't add 1) */
-			CAN_FDCBT_FPSEG1(6) |   /* Phase buffer segment 1 of 7 time quantas */
-			CAN_FDCBT_FPSEG2(4) |   /* Phase buffer segment 2 of 5 time quantas */
-			CAN_FDCBT_FRJW(4);      /* Resynchorinzation jump width same as PSEG2 */
-	putreg32(regval, S32K1XX_CAN0_FDCBT);
-
-	/* Additional CAN-FD configurations */
-	regval  = getreg32(S32K1XX_CAN0_FDCTRL);
-	regval |= CAN_FDCTRL_FDRATE | /* Enable bit rate switch in data phase of frame */
-			CAN_FDCTRL_TDCEN |  /* Enable transceiver delay compensation */
-			CAN_FDCTRL_TDCOFF(5) |   /* Setup 5 cycles for data phase sampling delay */
-			CAN_FDCTRL_MBDSR0(3);    /* Setup 64 bytes per message buffer (7 MB's) */
-	putreg32(regval, S32K1XX_CAN0_FDCTRL);
-
-	regval  = getreg32(S32K1XX_CAN0_CTRL2);
-	regval |= CAN_CTRL2_ISOCANFDEN;
-	putreg32(regval, S32K1XX_CAN0_CTRL2);
+  regval |= CAN_FDCTRL_FDRATE |     /* Enable bit rate switch in data phase of frame */
+            CAN_FDCTRL_TDCEN |      /* Enable transceiver delay compensation */
+            CAN_FDCTRL_TDCOFF(5) |  /* Setup 5 cycles for data phase sampling delay */
+            CAN_FDCTRL_MBDSR0(3);   /* Setup 64 bytes per message buffer (7 MB's) */
+  putreg32(regval, S32K1XX_CAN0_FDCTRL);
+
+  regval  = getreg32(S32K1XX_CAN0_CTRL2);
+  regval |= CAN_CTRL2_ISOCANFDEN;
+  putreg32(regval, S32K1XX_CAN0_CTRL2);
 #endif
 
-	for(i = TxMBCount; i < TotalMBcount; i++)
-	{
-		priv->rx[i].ID.w = 0x0;
-	}
+  for (i = TXMBCOUNT; i < TOTALMBCOUNT; i++)
+    {
+      priv->rx[i].id.w = 0x0;
+    }
 
-	putreg32(0x0, S32K1XX_CAN0_RXFGMASK);
+  putreg32(0x0, S32K1XX_CAN0_RXFGMASK);
 
-	for(i = 0; i < TotalMBcount; i++)
-	{
-		putreg32(0,S32K1XX_CAN0_RXIMR(i));
-	}
+  for (i = 0; i < TOTALMBCOUNT; i++)
+    {
+      putreg32(0, S32K1XX_CAN0_RXIMR(i));
+    }
 
-	putreg32(FIFO_IFLAG1 | TXMBMask, S32K1XX_CAN0_IFLAG1);
-	putreg32(FIFO_IFLAG1, S32K1XX_CAN0_IMASK1);
+  putreg32(FIFO_IFLAG1 | TXMBMASK, S32K1XX_CAN0_IFLAG1);
+  putreg32(FIFO_IFLAG1, S32K1XX_CAN0_IMASK1);
 
+  /* Exit freeze mode */
 
-	/* Exit freeze mode */
-	s32k1xx_setfreeze(0);
-	if(!s32k1xx_waitfreezeack_change(0))
-	{
-		ninfo("FLEXCAN: unfreeze fail\r\n");
-		return -1;
-	}
+  s32k1xx_setfreeze(0);
+  if (!s32k1xx_waitfreezeack_change(0))
+    {
+      ninfo("FLEXCAN: unfreeze fail\r\n");
+      return -1;
+    }
 
-	return 1;
+  return 1;
 }
 
 /****************************************************************************
@@ -1401,57 +1405,57 @@ static void s32k1xx_initbuffers(struct s32k1xx_driver_s *priv)
 
 static void s32k1xx_reset(struct s32k1xx_driver_s *priv)
 {
-	uint32_t regval;
-	uint32_t i;
-
-	regval  = getreg32(S32K1XX_CAN0_MCR);
-	regval |= CAN_MCR_SOFTRST;
-	putreg32(regval, S32K1XX_CAN0_MCR);
-
-	if(!s32k1xx_waitmcr_change(CAN_MCR_SOFTRST, 0))
-	{
-		nerr("Reset failed");
-		return;
-	}
-
-	/* TODO calculate TASD */
-
-
-	regval  = getreg32(S32K1XX_CAN0_MCR);
-	regval &= ~(CAN_MCR_SUPV);
-	putreg32(regval, S32K1XX_CAN0_MCR);
-
-	/* Initialize all MB rx and tx */
-	for(i = 0; i < TotalMBcount; i++)
-	{
-		ninfo("MB %i %p\r\n", i, &priv->rx[i]);
-		ninfo("MB %i %p\r\n", i, &priv->rx[i].ID.w);
-		priv->rx[i].CS.cs = 0x0;
-		priv->rx[i].ID.w = 0x0;
-		priv->rx[i].data.l = 0x0;
-		priv->rx[i].data.h = 0x0;
-	}
-
-	regval  = getreg32(S32K1XX_CAN0_MCR);
-	regval |= CAN_MCR_RFEN | CAN_MCR_SLFWAK | CAN_MCR_WRNEN | CAN_MCR_SRXDIS
-			| CAN_MCR_IRMQ | CAN_MCR_AEN |
-			(((TotalMBcount - 1) << CAN_MCR_MAXMB_SHIFT) & CAN_MCR_MAXMB_MASK);
-	putreg32(regval, S32K1XX_CAN0_MCR);
-
-	regval  = CAN_CTRL2_RRS | CAN_CTRL2_EACEN | CAN_CTRL2_RFFN_16MB; //FIXME TASD
-	putreg32(regval, S32K1XX_CAN0_CTRL2);
-
-
-	for(i = 0; i < TotalMBcount; i++)
-	{
-		putreg32(0,S32K1XX_CAN0_RXIMR(i));
-	}
-
-	/* Filtering catchall */
-	putreg32(0x3FFFFFFF, S32K1XX_CAN0_RX14MASK);
-	putreg32(0x3FFFFFFF, S32K1XX_CAN0_RX15MASK);
-	putreg32(0x3FFFFFFF, S32K1XX_CAN0_RXMGMASK);
-	putreg32(0x0, S32K1XX_CAN0_RXFGMASK);
+  uint32_t regval;
+  uint32_t i;
+
+  regval  = getreg32(S32K1XX_CAN0_MCR);
+  regval |= CAN_MCR_SOFTRST;
+  putreg32(regval, S32K1XX_CAN0_MCR);
+
+  if (!s32k1xx_waitmcr_change(CAN_MCR_SOFTRST, 0))
+    {
+      nerr("Reset failed");
+      return;
+    }
+
+  /* TODO calculate TASD */
+
+  regval  = getreg32(S32K1XX_CAN0_MCR);
+  regval &= ~(CAN_MCR_SUPV);
+  putreg32(regval, S32K1XX_CAN0_MCR);
+
+  /* Initialize all MB rx and tx */
+
+  for (i = 0; i < TOTALMBCOUNT; i++)
+    {
+      ninfo("MB %i %p\r\n", i, &priv->rx[i]);
+      ninfo("MB %i %p\r\n", i, &priv->rx[i].id.w);
+      priv->rx[i].cs.cs = 0x0;
+      priv->rx[i].id.w = 0x0;
+      priv->rx[i].data.l = 0x0;
+      priv->rx[i].data.h = 0x0;
+    }
+
+  regval  = getreg32(S32K1XX_CAN0_MCR);
+  regval |= CAN_MCR_RFEN | CAN_MCR_SLFWAK | CAN_MCR_WRNEN | CAN_MCR_SRXDIS |
+            CAN_MCR_IRMQ | CAN_MCR_AEN |
+            (((TOTALMBCOUNT - 1) << CAN_MCR_MAXMB_SHIFT) & CAN_MCR_MAXMB_MASK);
+  putreg32(regval, S32K1XX_CAN0_MCR);
+
+  regval  = CAN_CTRL2_RRS | CAN_CTRL2_EACEN | CAN_CTRL2_RFFN_16MB; /* FIXME TASD */
+  putreg32(regval, S32K1XX_CAN0_CTRL2);
+
+  for (i = 0; i < TOTALMBCOUNT; i++)
+    {
+      putreg32(0, S32K1XX_CAN0_RXIMR(i));
+    }
+
+  /* Filtering catchall */
+
+  putreg32(0x3fffffff, S32K1XX_CAN0_RX14MASK);
+  putreg32(0x3fffffff, S32K1XX_CAN0_RX15MASK);
+  putreg32(0x3fffffff, S32K1XX_CAN0_RXMGMASK);
+  putreg32(0x0, S32K1XX_CAN0_RXFGMASK);
 }
 
 /****************************************************************************
@@ -1480,7 +1484,8 @@ int s32k1xx_netinitialize(int intf)
   struct s32k1xx_driver_s *priv;
   int ret;
 
-  //FIXME dynamic board config
+  /* FIXME dynamic board config */
+
   s32k1xx_pinconfig(PIN_CAN0_TX_4);
   s32k1xx_pinconfig(PIN_CAN0_RX_4);
 
@@ -1490,10 +1495,10 @@ int s32k1xx_netinitialize(int intf)
 
   /* Get the interface structure associated with this interface number. */
 
-    #warning Missing logic
-
+#warning Missing logic
 
   /* Attach the flexcan interrupt handler */
+
   if (irq_attach(S32K1XX_IRQ_CAN0_BUS, s32k1xx_flexcan_interrupt, NULL))
     {
       /* We could not attach the ISR to the interrupt */
@@ -1501,6 +1506,7 @@ int s32k1xx_netinitialize(int intf)
       nerr("ERROR: Failed to attach CAN bus IRQ\n");
       return -EAGAIN;
     }
+
   if (irq_attach(S32K1XX_IRQ_CAN0_ERROR, s32k1xx_flexcan_interrupt, NULL))
     {
       /* We could not attach the ISR to the interrupt */
@@ -1508,6 +1514,7 @@ int s32k1xx_netinitialize(int intf)
       nerr("ERROR: Failed to attach CAN error IRQ\n");
       return -EAGAIN;
     }
+
   if (irq_attach(S32K1XX_IRQ_CAN0_LPRX, s32k1xx_flexcan_interrupt, NULL))
     {
       /* We could not attach the ISR to the interrupt */
@@ -1515,6 +1522,7 @@ int s32k1xx_netinitialize(int intf)
       nerr("ERROR: Failed to attach CAN LPRX IRQ\n");
       return -EAGAIN;
     }
+
   if (irq_attach(S32K1XX_IRQ_CAN0_0_15, s32k1xx_flexcan_interrupt, NULL))
     {
       /* We could not attach the ISR to the interrupt */
@@ -1526,20 +1534,21 @@ int s32k1xx_netinitialize(int intf)
   /* Initialize the driver structure */
 
   memset(priv, 0, sizeof(struct s32k1xx_driver_s));
-  priv->dev.d_ifup    = s32k1xx_ifup;     /* I/F up (new IP address) callback */
-  priv->dev.d_ifdown  = s32k1xx_ifdown;   /* I/F down callback */
-  priv->dev.d_txavail = s32k1xx_txavail;  /* New TX data callback */
+  priv->dev.d_ifup    = s32k1xx_ifup;      /* I/F up (new IP address) callback */
+  priv->dev.d_ifdown  = s32k1xx_ifdown;    /* I/F down callback */
+  priv->dev.d_txavail = s32k1xx_txavail;   /* New TX data callback */
 #ifdef CONFIG_NETDEV_IOCTL
-  priv->dev.d_ioctl   = s32k1xx_ioctl;    /* Support PHY ioctl() calls */
+  priv->dev.d_ioctl   = s32k1xx_ioctl;     /* Support PHY ioctl() calls */
 #endif
-  priv->dev.d_private = (void *)g_flexcan;   /* Used to recover private state from dev */
+  priv->dev.d_private = (void *)g_flexcan; /* Used to recover private state from dev */
 
   /* Create a watchdog for timing polling for and timing of transmissions */
-  priv->txpoll        = wd_create();      /* Create periodic poll timer */
-  priv->txtimeout     = wd_create();      /* Create TX timeout timer */
-  priv->rx            = (struct MbRx *)(S32K1XX_CAN0_MB);
-  priv->tx            = (struct MbTx *)(S32K1XX_CAN0_MB + (sizeof(struct MbRx)
-		                                * RxMBCount) );
+
+  priv->txpoll        = wd_create();       /* Create periodic poll timer */
+  priv->txtimeout     = wd_create();       /* Create TX timeout timer */
+  priv->rx            = (struct mbrx_s *)(S32K1XX_CAN0_MB);
+  priv->tx            = (struct mbtx_s *)(S32K1XX_CAN0_MB +
+                          (sizeof(struct mbrx_s) * RXMBCOUNT));
 
   /* Put the interface in the down state.  This usually amounts to resetting
    * the device and/or calling s32k1xx_ifdown().
@@ -1568,7 +1577,7 @@ int s32k1xx_netinitialize(int intf)
  *
  ****************************************************************************/
 
-//FIXME CONFIG_S32K1XX_FLEXCAN_NETHIFS == 1 && 
+/* FIXME CONFIG_S32K1XX_FLEXCAN_NETHIFS == 1 && */
 
 #if !defined(CONFIG_NETDEV_LATEINIT)
 void up_netinitialize(void)
diff --git a/include/netpacket/can.h b/include/netpacket/can.h
index 45edab5..0b4c7b9 100644
--- a/include/netpacket/can.h
+++ b/include/netpacket/can.h
@@ -126,13 +126,13 @@ struct sockaddr_can
          *   1 bit: reserved
          */
 
-      uint32_t pgn;
+        uint32_t pgn;
 
-      /* 1 byte address */
+        /* 1 byte address */
 
-      uint8_t addr;
-    } j1939;
-  } can_addr;
+        uint8_t addr;
+      } j1939;
+    } can_addr;
 };
 
 #endif /* __INCLUDE_NETPACKET_CAN_H */
diff --git a/include/nuttx/can.h b/include/nuttx/can.h
index 02f80a8..7a66a65 100644
--- a/include/nuttx/can.h
+++ b/include/nuttx/can.h
@@ -53,7 +53,6 @@
  * Pre-processor Definitions
  ************************************************************************************/
 
-
 /* Ioctl Commands *******************************************************************/
 
 /* Ioctl commands supported by the upper half CAN driver.
@@ -185,61 +184,17 @@
  *   CAN_B_NCMDS                 77                          <- Number of commands
  */
 
-/************************************************************************************
- * Public Types
- ************************************************************************************/
-
-typedef FAR void *CAN_HANDLE;
-
-struct can_response_s
-{
-  sq_entry_t flink;
-
-  /* Message-specific data may follow */
-}; //FIXME remvoe
-
-
-typedef uint32_t canid_t;
-
-/*
- * Controller Area Network Error Message Frame Mask structure
- *
- * bit 0-28	: error class mask (see include/uapi/linux/can/error.h)
- * bit 29-31	: set to zero
- */
-typedef uint32_t can_err_mask_t;
-
 /* CAN payload length and DLC definitions according to ISO 11898-1 */
+
 #define CAN_MAX_DLC 8
 #define CAN_MAX_DLEN 8
 
 /* CAN FD payload length and DLC definitions according to ISO 11898-7 */
+
 #define CANFD_MAX_DLC 15
 #define CANFD_MAX_DLEN 64
 
-
-/**
- * struct can_frame - basic CAN frame structure
- * @can_id:  CAN ID of the frame and CAN_*_FLAG flags, see canid_t definition
- * @can_dlc: frame payload length in byte (0 .. 8) aka data length code
- *           N.B. the DLC field from ISO 11898-1 Chapter 8.4.2.3 has a 1:1
- *           mapping of the 'data length code' to the real payload length
- * @__pad:   padding
- * @__res0:  reserved / padding
- * @__res1:  reserved / padding
- * @data:    CAN frame payload (up to 8 byte)
- */
-struct can_frame {
-	canid_t can_id;  /* 32 bit CAN_ID + EFF/RTR/ERR flags */
-	uint8_t    can_dlc; /* frame payload length in byte (0 .. CAN_MAX_DLEN) */
-	uint8_t    __pad;   /* padding */
-	uint8_t    __res0;  /* reserved / padding */
-	uint8_t    __res1;  /* reserved / padding */
-	uint8_t    data[CAN_MAX_DLEN] __attribute__((aligned(8)));
-};
-
-/*
- * defined bits for canfd_frame.flags
+/* Defined bits for canfd_frame.flags
  *
  * The use of struct canfd_frame implies the Extended Data Length (EDL) bit to
  * be set in the CAN frame bitstream on the wire. The EDL bit switch turns
@@ -254,48 +209,94 @@ struct can_frame {
  * building a CAN FD frame for transmission. Setting the CANFD_ESI bit can make
  * sense for virtual CAN interfaces to test applications with echoed frames.
  */
+
 #define CANFD_BRS 0x01 /* bit rate switch (second bitrate for payload data) */
 #define CANFD_ESI 0x02 /* error state indicator of the transmitting node */
 
-/**
- * struct canfd_frame - CAN flexible data rate frame structure
- * @can_id: CAN ID of the frame and CAN_*_FLAG flags, see canid_t definition
- * @len:    frame payload length in byte (0 .. CANFD_MAX_DLEN)
- * @flags:  additional flags for CAN FD
- * @__res0: reserved / padding
- * @__res1: reserved / padding
- * @data:   CAN FD frame payload (up to CANFD_MAX_DLEN byte)
+#define CAN_INV_FILTER     0x20000000U /* to be set in can_filter.can_id */
+#define CAN_RAW_FILTER_MAX 512         /* maximum number of can_filter set via setsockopt() */
+
+/************************************************************************************
+ * Public Types
+ ************************************************************************************/
+
+typedef FAR void *CAN_HANDLE;
+
+struct can_response_s
+{
+  sq_entry_t flink;
+
+  /* Message-specific data may follow */
+}; /* FIXME remove */
+
+typedef uint32_t canid_t;
+
+/* Controller Area Network Error Message Frame Mask structure
+ *
+ * bit 0-28  : error class mask (see include/uapi/linux/can/error.h)
+ * bit 29-31 : set to zero
  */
-struct canfd_frame {
-	canid_t can_id;  /* 32 bit CAN_ID + EFF/RTR/ERR flags */
-	uint8_t    len;     /* frame payload length in byte */
-	uint8_t    flags;   /* additional flags for CAN FD */
-	uint8_t    __res0;  /* reserved / padding */
-	uint8_t    __res1;  /* reserved / padding */
-	uint8_t    data[CANFD_MAX_DLEN] __attribute__((aligned(8)));
+
+typedef uint32_t can_err_mask_t;
+
+/* struct can_frame - basic CAN frame structure
+ * can_id:  CAN ID of the frame and CAN_*_FLAG flags, see canid_t definition
+ * can_dlc: frame payload length in byte (0 .. 8) aka data length code
+ *          N.B. the DLC field from ISO 11898-1 Chapter 8.4.2.3 has a 1:1
+ *          mapping of the 'data length code' to the real payload length
+ * __pad:   padding
+ * __res0:  reserved / padding
+ * __res1:  reserved / padding
+ * data:    CAN frame payload (up to 8 byte)
+ */
+
+struct can_frame
+{
+  canid_t can_id;   /* 32 bit CAN_ID + EFF/RTR/ERR flags */
+  uint8_t  can_dlc; /* frame payload length in byte (0 .. CAN_MAX_DLEN) */
+  uint8_t  __pad;   /* padding */
+  uint8_t  __res0;  /* reserved / padding */
+  uint8_t  __res1;  /* reserved / padding */
+  uint8_t  data[CAN_MAX_DLEN] __attribute__((aligned(8)));
 };
 
+/* struct canfd_frame - CAN flexible data rate frame structure
+ * can_id: CAN ID of the frame and CAN_*_FLAG flags, see canid_t definition
+ * len:    frame payload length in byte (0 .. CANFD_MAX_DLEN)
+ * flags:  additional flags for CAN FD
+ * __res0: reserved / padding
+ * __res1: reserved / padding
+ * data:   CAN FD frame payload (up to CANFD_MAX_DLEN byte)
+ */
+
+struct canfd_frame
+{
+  canid_t can_id;  /* 32 bit CAN_ID + EFF/RTR/ERR flags */
+  uint8_t len;     /* frame payload length in byte */
+  uint8_t flags;   /* additional flags for CAN FD */
+  uint8_t __res0;  /* reserved / padding */
+  uint8_t __res1;  /* reserved / padding */
+  uint8_t data[CANFD_MAX_DLEN] __attribute__((aligned(8)));
+};
 
-/**
- * struct can_filter - CAN ID based filter in can_register().
- * @can_id:   relevant bits of CAN ID which are not masked out.
- * @can_mask: CAN mask (see description)
+/* struct can_filter - CAN ID based filter in can_register().
+ * can_id:   relevant bits of CAN ID which are not masked out.
+ * can_mask: CAN mask (see description)
  *
  * Description:
  * A filter matches, when
  *
- *          <received_can_id> & mask == can_id & mask
+ *   <received_can_id> & mask == can_id & mask
  *
  * The filter can be inverted (CAN_INV_FILTER bit set in can_id) or it can
  * filter for error message frames (CAN_ERR_FLAG bit set in mask).
  */
-struct can_filter {
-	canid_t can_id;
-	canid_t can_mask;
-};
 
-#define CAN_INV_FILTER 0x20000000U /* to be set in can_filter.can_id */
-#define CAN_RAW_FILTER_MAX 512 /* maximum number of can_filter set via setsockopt() */
+struct can_filter
+{
+  canid_t can_id;
+  canid_t can_mask;
+};
 
 /************************************************************************************
  * Public Function Prototypes
@@ -310,7 +311,6 @@ extern "C"
 #define EXTERN extern
 #endif
 
-
 #undef EXTERN
 #if defined(__cplusplus)
 }
diff --git a/include/nuttx/mm/iob.h b/include/nuttx/mm/iob.h
index cabd2ff..5903c50 100644
--- a/include/nuttx/mm/iob.h
+++ b/include/nuttx/mm/iob.h
@@ -54,6 +54,7 @@
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
+
 /* Configuration ************************************************************/
 
 /* I/O buffer allocation logic supports a throttle value for read-ahead
diff --git a/include/sys/socket.h b/include/sys/socket.h
index bc7cd26..4cf40a7 100644
--- a/include/sys/socket.h
+++ b/include/sys/socket.h
@@ -131,7 +131,7 @@
 
 /* Protocol levels supported by get/setsockopt(): */
 
-#define SOL_SOCKET      0 /* Only socket-level options supported */
+#define SOL_SOCKET       0 /* Only socket-level options supported */
 
 /* Socket-level options */
 
@@ -202,13 +202,13 @@
                             * return: int
                             */
 
-                            
 /* The options are unsupported but included for compatibility
  * and portability
  */
+
 #define SO_TIMESTAMP    29
-#define SO_SNDBUFFORCE	32 
-#define SO_RCVBUFFORCE	33 
+#define SO_SNDBUFFORCE  32
+#define SO_RCVBUFFORCE  33
 #define SO_RXQ_OVFL     40
 
 /* Protocol-level socket operations. */
diff --git a/net/can/can.h b/net/can/can.h
index 46c7425..67c8d6f 100644
--- a/net/can/can.h
+++ b/net/can/can.h
@@ -85,26 +85,25 @@ struct can_conn_s
   FAR struct devif_callback_s *list; /* NetLink callbacks */
 
   FAR struct net_driver_s *dev;      /* Reference to CAN device */
-  
+
   /* Read-ahead buffering.
    *
    *   readahead - A singly linked list of type struct iob_qentry_s
    *               where the CAN/IP read-ahead data is retained.
    */
 
-  struct iob_queue_s readahead;   /* remove Read-ahead buffering */
+  struct iob_queue_s readahead;      /* remove Read-ahead buffering */
 
   /* CAN-specific content follows */
 
   uint8_t protocol;                  /* Selected CAN protocol */
   int16_t crefs;                     /* Reference count */
-  
 
   /* The following is a list of poll structures of threads waiting for
    * socket events.
    */
 
-  struct can_poll_s pollinfo[4]; //FIXME make dynamic
+  struct can_poll_s pollinfo[4]; /* FIXME make dynamic */
 };
 
 /****************************************************************************
@@ -223,9 +222,9 @@ uint16_t can_datahandler(FAR struct can_conn_s *conn, FAR uint8_t *buffer,
  * Name: can_recvfrom
  *
  * Description:
- *   Implements the socket recvfrom interface pkt_recvfrom() receives messages from
- *   a socket, and may be used to receive data on a socket whether or not it
- *   is connection-oriented.
+ *   Implements the socket recvfrom interface pkt_recvfrom() receives
+ *   messages from a socket, and may be used to receive data on a socket
+ *   whether or not it is connection-oriented.
  *
  * Input Parameters:
  *   psock    A pointer to a NuttX-specific, internal socket structure
@@ -315,7 +314,6 @@ ssize_t psock_can_send(FAR struct socket *psock, FAR const void *buf,
 void can_readahead_signal(FAR struct can_conn_s *conn);
 #endif
 
-
 #undef EXTERN
 #ifdef __cplusplus
 }
diff --git a/net/can/can_callback.c b/net/can/can_callback.c
index 6f3ae93..c61bdce 100644
--- a/net/can/can_callback.c
+++ b/net/can/can_callback.c
@@ -1,35 +1,20 @@
 /****************************************************************************
  * net/pkt/pkt_callback.c
  *
- *   Copyright (C) 2014 Gregory Nutt. All rights reserved.
- *   Author: Gregory Nutt <gn...@nuttx.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- *    used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
  *
  ****************************************************************************/
 
@@ -72,17 +57,15 @@ can_data_event(FAR struct net_driver_s *dev, FAR struct can_conn_s *conn,
                uint16_t flags)
 {
   uint16_t ret;
-  uint8_t *buffer = dev->d_appdata;
-  int      buflen = dev->d_len;
+  FAR uint8_t *buffer = dev->d_appdata;
+  int buflen = dev->d_len;
   uint16_t recvlen;
 
   ret = (flags & ~CAN_NEWDATA);
 
-  //ninfo("No listener on connection\n");
-
-   /* Save as the packet data as in the read-ahead buffer.  NOTE that
-    * partial packets will not be buffered.
-    */
+  /* Save as the packet data as in the read-ahead buffer.  NOTE that
+   * partial packets will not be buffered.
+   */
 
   recvlen = can_datahandler(conn, buffer, buflen);
   if (recvlen < buflen)
@@ -94,10 +77,11 @@ can_data_event(FAR struct net_driver_s *dev, FAR struct can_conn_s *conn,
       ninfo("Dropped %d bytes\n", dev->d_len);
 
 #ifdef CONFIG_NET_STATISTICS
-      //g_netstats.tcp.drop++;
+      /* g_netstats.tcp.drop++; */
+
 #endif
     }
-        
+
   /* In any event, the new data has now been handled */
 
   dev->d_len = 0;
@@ -132,15 +116,15 @@ uint16_t can_callback(FAR struct net_driver_s *dev,
       /* Perform the callback */
 
       flags = devif_conn_event(dev, conn, flags, conn->list);
-    
-    if ((flags & CAN_NEWDATA) != 0)
-      {
-        /* Data was not handled.. dispose of it appropriately */
-
-        flags = can_data_event(dev, conn, flags);
-      }
-  }
-  
+
+      if ((flags & CAN_NEWDATA) != 0)
+        {
+          /* Data was not handled.. dispose of it appropriately */
+
+          flags = can_data_event(dev, conn, flags);
+        }
+    }
+
   return flags;
 }
 
@@ -214,7 +198,7 @@ uint16_t can_datahandler(FAR struct can_conn_s *conn, FAR uint8_t *buffer,
       iob_free_chain(iob, IOBUSER_NET_TCP_READAHEAD);
       return 0;
     }
-    
+
 #ifdef CONFIG_NET_CAN_NOTIFIER
   /* Provide notification(s) that additional CAN read-ahead data is
    * available.
diff --git a/net/can/can_getsockopt.c b/net/can/can_getsockopt.c
index d9e19f8..1fe8218 100644
--- a/net/can/can_getsockopt.c
+++ b/net/can/can_getsockopt.c
@@ -1,35 +1,20 @@
 /****************************************************************************
  * net/can/can_setsockopt.c
  *
- *   Copyright (C) 2018 Gregory Nutt. All rights reserved.
- *   Author: Gregory Nutt <gn...@nuttx.org>
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- *    used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
  *
  ****************************************************************************/
 
@@ -89,10 +74,9 @@
  *
  ****************************************************************************/
 
-int can_getsockopt  (FAR struct socket *psock, int option,
+int can_getsockopt(FAR struct socket *psock, int option,
                    FAR void *value, FAR socklen_t *value_len)
 {
-
   FAR struct can_conn_s *conn;
   int ret;
   int count = 0;
@@ -107,38 +91,37 @@ int can_getsockopt  (FAR struct socket *psock, int option,
       return -ENOTCONN;
     }
 
-
   switch (option)
     {
-      
       case CAN_RAW_FILTER:
         if (*value_len % sizeof(struct can_filter) != 0)
-        {
-		  ret = -EINVAL;
-        }
-        
+          {
+            ret = -EINVAL;
+          }
+
         if (value_len > CAN_RAW_FILTER_MAX * sizeof(struct can_filter))
-        {
-		  ret = -EINVAL;
-        }
+          {
+            ret = -EINVAL;
+          }
+
+        count = *value_len / sizeof(struct can_filter);
 
-		count = *value_len / sizeof(struct can_filter);
-        
         /* FIXME pass filter to driver */
+
         break;
-      
+
       case CAN_RAW_ERR_FILTER:
         break;
-      
+
       case CAN_RAW_LOOPBACK:
         break;
-      
+
       case CAN_RAW_RECV_OWN_MSGS:
         break;
-      
+
       case CAN_RAW_FD_FRAMES:
         break;
-      
+
       case CAN_RAW_JOIN_FILTERS:
         break;
 
diff --git a/net/can/can_input.c b/net/can/can_input.c
index 32dcebf..30e2507 100644
--- a/net/can/can_input.c
+++ b/net/can/can_input.c
@@ -2,39 +2,20 @@
  * net/can/can_input.c
  * Handling incoming packet input
  *
- *   Copyright (C) 2014, 2020 Gregory Nutt. All rights reserved.
- *   Author: Gregory Nutt <gn...@nuttx.org>
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
  *
- * Adapted for NuttX from logic in uIP which also has a BSD-like license:
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
- *   Original author Adam Dunkels <ad...@dunkels.com>
- *   Copyright () 2001-2003, Adam Dunkels.
- *   All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
  *
  ****************************************************************************/
 
@@ -55,11 +36,6 @@
 #include "can/can.h"
 
 /****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-
-/****************************************************************************
  * Public Functions
  ****************************************************************************/
 
@@ -88,7 +64,7 @@ int can_input(struct net_driver_s *dev)
   FAR struct can_conn_s *conn;
   int ret = OK;
 
-  conn = can_nextconn(NULL); //FIXME 
+  conn = can_nextconn(NULL); /* FIXME  */
   if (conn)
     {
       uint16_t flags;
diff --git a/net/can/can_poll.c b/net/can/can_poll.c
index 80e59a2..77fe24c 100644
--- a/net/can/can_poll.c
+++ b/net/can/can_poll.c
@@ -2,39 +2,20 @@
  * net/pkt/pkt_poll.c
  * Poll for the availability of packet TX data
  *
- *   Copyright (C) 2014 Gregory Nutt. All rights reserved.
- *   Author: Gregory Nutt <gn...@nuttx.org>
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
  *
- * Adapted for NuttX from logic in uIP which also has a BSD-like license:
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
- *   Original author Adam Dunkels <ad...@dunkels.com>
- *   Copyright () 2001-2003, Adam Dunkels.
- *   All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
  *
  ****************************************************************************/
 
@@ -88,13 +69,15 @@ void can_poll(FAR struct net_driver_s *dev, FAR struct can_conn_s *conn)
       dev->d_sndlen  = 0;
 
       /* Perform the application callback */
+
       can_callback(dev, conn, CAN_POLL);
 
       /* Check if the application has data to send */
 
       if (dev->d_sndlen > 0)
         {
-            //FIXME missing logic
+          /* FIXME missing logic */
+
           return;
         }
     }
diff --git a/net/can/can_recvfrom.c b/net/can/can_recvfrom.c
index 990786d..d2f71a6 100644
--- a/net/can/can_recvfrom.c
+++ b/net/can/can_recvfrom.c
@@ -1,36 +1,20 @@
 /****************************************************************************
  * net/can/can_recvfrom.c
  *
- *   Copyright (C) 2007-2009, 2011-2017, 2020 Gregory Nutt. All rights
- *     reserved.
- *   Author: Gregory Nutt <gn...@nuttx.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- *    used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
  *
  ****************************************************************************/
 
@@ -146,7 +130,6 @@ static size_t can_recvfrom_newdata(FAR struct net_driver_s *dev,
   /* Copy the new packet data into the user buffer */
 
   memcpy(pstate->pr_buffer, dev->d_buf, recvlen);
-  //ninfo("Received %d bytes (of %d)\n", (int)recvlen, (int)dev->d_len);
 
   /* Update the accumulated size of the data read */
 
@@ -155,7 +138,6 @@ static size_t can_recvfrom_newdata(FAR struct net_driver_s *dev,
   return recvlen;
 }
 
-
 /****************************************************************************
  * Name: can_newdata
  *
@@ -187,7 +169,8 @@ static inline void can_newdata(FAR struct net_driver_s *dev,
 
   if (recvlen < dev->d_len)
     {
-      FAR struct can_conn_s *conn = (FAR struct can_conn_s *)pstate->pr_sock->s_conn;
+      FAR struct can_conn_s *conn =
+        (FAR struct can_conn_s *)pstate->pr_sock->s_conn;
       FAR uint8_t *buffer = (FAR uint8_t *)dev->d_appdata + recvlen;
       uint16_t buflen = dev->d_len - recvlen;
 #ifdef CONFIG_DEBUG_NET
@@ -249,8 +232,8 @@ static inline int can_readahead(struct can_recvfrom_s *pstate)
    * buffer.
    */
 
-  if((iob = iob_peek_queue(&conn->readahead)) != NULL &&
-          pstate->pr_buflen > 0)
+  if ((iob = iob_peek_queue(&conn->readahead)) != NULL &&
+      pstate->pr_buflen > 0)
     {
       DEBUGASSERT(iob->io_pktlen > 0);
 
@@ -292,9 +275,11 @@ static inline int can_readahead(struct can_recvfrom_s *pstate)
           iob_trimhead_queue(&conn->readahead, recvlen,
                              IOBUSER_NET_CAN_READAHEAD);
         }
-        return recvlen;
+
+      return recvlen;
     }
-    return 0;
+
+  return 0;
 }
 
 static uint16_t can_recvfrom_eventhandler(FAR struct net_driver_s *dev,
@@ -303,8 +288,6 @@ static uint16_t can_recvfrom_eventhandler(FAR struct net_driver_s *dev,
 {
   struct can_recvfrom_s *pstate = (struct can_recvfrom_s *)pvpriv;
 
-  //ninfo("flags: %04x\n", flags);
-
   /* 'priv' might be null in some race conditions (?) */
 
   if (pstate)
@@ -319,17 +302,17 @@ static uint16_t can_recvfrom_eventhandler(FAR struct net_driver_s *dev,
 
           /* We are finished. */
 
-          //ninfo("CAN done\n");
-
           /* Don't allow any further call backs. */
 
           pstate->pr_cb->flags   = 0;
           pstate->pr_cb->priv    = NULL;
           pstate->pr_cb->event   = NULL;
 
+#if 0
           /* Save the sender's address in the caller's 'from' location */
 
-          //pkt_recvfrom_sender(dev, pstate);
+          pkt_recvfrom_sender(dev, pstate);
+#endif
 
           /* indicate that the data has been consumed */
 
@@ -429,16 +412,15 @@ ssize_t can_recvfrom(FAR struct socket *psock, FAR void *buf,
               (fromlen != NULL && *fromlen >= sizeof(struct sockaddr_can)));
 
   conn = (FAR struct can_conn_s *)psock->s_conn;
-  
+
   if (psock->s_type != SOCK_RAW)
     {
       nerr("ERROR: Unsupported socket type: %d\n", psock->s_type);
       ret = -ENOSYS;
     }
-  
-  
+
   net_lock();
-  
+
   /* Initialize the state structure. */
 
   memset(&state, 0, sizeof(struct can_recvfrom_s));
@@ -453,19 +435,20 @@ ssize_t can_recvfrom(FAR struct socket *psock, FAR void *buf,
   state.pr_buflen = len;
   state.pr_buffer = buf;
   state.pr_sock   = psock;
-  
+
   /* Handle any any CAN data already buffered in a read-ahead buffer.  NOTE
    * that there may be read-ahead data to be retrieved even after the
    * socket has been disconnected.
    */
+
   ret = can_readahead(&state);
-  if(ret > 0)
-  {
+  if (ret > 0)
+    {
       net_unlock();
       nxsem_destroy(&state.pr_sem);
       return ret;
-  }    
-  
+    }
+
   /* Get the device driver that will service this transfer */
 
   dev  = conn->dev;
@@ -474,7 +457,7 @@ ssize_t can_recvfrom(FAR struct socket *psock, FAR void *buf,
       ret = -ENODEV;
       goto errout_with_state;
     }
-    
+
   /* Set up the callback in the connection */
 
   state.pr_cb = can_callback_alloc(dev, conn);
@@ -502,7 +485,6 @@ ssize_t can_recvfrom(FAR struct socket *psock, FAR void *buf,
       ret = -EBUSY;
     }
 
-  
 errout_with_state:
   net_unlock();
   nxsem_destroy(&state.pr_sem);
diff --git a/net/can/can_setsockopt.c b/net/can/can_setsockopt.c
index db4cb76..2d117a8 100644
--- a/net/can/can_setsockopt.c
+++ b/net/can/can_setsockopt.c
@@ -1,35 +1,20 @@
 /****************************************************************************
  * net/can/can_setsockopt.c
  *
- *   Copyright (C) 2018, 2020 Gregory Nutt. All rights reserved.
- *   Author: Gregory Nutt <gn...@nuttx.org>
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- *    used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
  *
  ****************************************************************************/
 
@@ -87,7 +72,6 @@
 int can_setsockopt(FAR struct socket *psock, int option,
                    FAR const void *value, socklen_t value_len)
 {
-    
   FAR struct can_conn_s *conn;
   int ret;
   int count = 0;
@@ -101,37 +85,37 @@ int can_setsockopt(FAR struct socket *psock, int option,
       return -ENOTCONN;
     }
 
-
   switch (option)
     {
       case CAN_RAW_FILTER:
         if (value_len % sizeof(struct can_filter) != 0)
-        {
-		  ret = -EINVAL;
-        }
-        
+          {
+            ret = -EINVAL;
+          }
+
         if (value_len > CAN_RAW_FILTER_MAX * sizeof(struct can_filter))
-        {
-		  ret = -EINVAL;
-        }
+          {
+            ret = -EINVAL;
+          }
+
+        count = value_len / sizeof(struct can_filter);
 
-		count = value_len / sizeof(struct can_filter);
-        
         /* FIXME pass filter to driver */
+
         break;
-      
+
       case CAN_RAW_ERR_FILTER:
         break;
-      
+
       case CAN_RAW_LOOPBACK:
         break;
-      
+
       case CAN_RAW_RECV_OWN_MSGS:
         break;
-      
+
       case CAN_RAW_FD_FRAMES:
         break;
-      
+
       case CAN_RAW_JOIN_FILTERS:
         break;
 
diff --git a/net/can/can_sockif.c b/net/can/can_sockif.c
index 5c8415e..573ddd8 100644
--- a/net/can/can_sockif.c
+++ b/net/can/can_sockif.c
@@ -96,7 +96,6 @@ const struct sock_intf_s g_can_sockif =
   can_close         /* si_close */
 };
 
-
 /****************************************************************************
  * Private Functions
  ****************************************************************************/
@@ -149,12 +148,14 @@ static uint16_t can_poll_eventhandler(FAR struct net_driver_s *dev,
           eventset |= (POLLHUP | POLLERR);
         }
 
+#if 0
       /* A poll is a sign that we are free to send data. */
 
-     /* else if ((flags & CAN_POLL) != 0 && psock_udp_cansend(info->psock) >= 0)
+      else if ((flags & CAN_POLL) != 0 && psock_udp_cansend(info->psock) >= 0)
         {
           eventset |= (POLLOUT & info->fds->events);
-        }*/
+        }
+#endif
 
       /* Awaken the caller of poll() is requested event occurred. */
 
@@ -326,23 +327,23 @@ static void can_addref(FAR struct socket *psock)
  ****************************************************************************/
 
 static int can_bind(FAR struct socket *psock,
-                        FAR const struct sockaddr *addr, socklen_t addrlen)
+                    FAR const struct sockaddr *addr, socklen_t addrlen)
 {
   FAR struct sockaddr_can *canaddr;
   FAR struct can_conn_s *conn;
+  char netdev_name[6];
 
   DEBUGASSERT(psock != NULL && psock->s_conn != NULL && addr != NULL &&
               addrlen >= sizeof(struct sockaddr_can));
 
   /* Save the address information in the connection structure */
 
-  canaddr         = (FAR struct sockaddr_can *)addr;
-  conn            = (FAR struct can_conn_s *)psock->s_conn;
+  canaddr = (FAR struct sockaddr_can *)addr;
+  conn    = (FAR struct can_conn_s *)psock->s_conn;
 
   /* Bind CAN device to socket */
 
-  //TODO better support for CONFIG_NETDEV_IFINDEX
-  char netdev_name[6];
+  /* TODO better support for CONFIG_NETDEV_IFINDEX */
 
   sprintf(netdev_name, "can%i", canaddr->can_ifindex);
 
@@ -374,8 +375,8 @@ static int can_bind(FAR struct socket *psock,
  ****************************************************************************/
 
 static int can_getsockname(FAR struct socket *psock,
-                               FAR struct sockaddr *addr,
-                               FAR socklen_t *addrlen)
+                           FAR struct sockaddr *addr,
+                           FAR socklen_t *addrlen)
 {
   FAR struct sockaddr_can *canaddr;
 
@@ -430,8 +431,8 @@ static int can_getsockname(FAR struct socket *psock,
  ****************************************************************************/
 
 static int can_getpeername(FAR struct socket *psock,
-                               FAR struct sockaddr *addr,
-                               FAR socklen_t *addrlen)
+                           FAR struct sockaddr *addr,
+                           FAR socklen_t *addrlen)
 {
 #warning Missing logic
   return -EOPNOTSUPP;  /* Or maybe return -EAFNOSUPPORT; */
@@ -488,8 +489,8 @@ static int can_listen(FAR struct socket *psock, int backlog)
  ****************************************************************************/
 
 static int can_connect(FAR struct socket *psock,
-                           FAR const struct sockaddr *addr,
-                           socklen_t addrlen)
+                       FAR const struct sockaddr *addr,
+                       socklen_t addrlen)
 {
 #warning Missing logic
   return -EOPNOTSUPP;
@@ -540,7 +541,7 @@ static int can_connect(FAR struct socket *psock,
  ****************************************************************************/
 
 static int can_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
-                          FAR socklen_t *addrlen, FAR struct socket *newsock)
+                      FAR socklen_t *addrlen, FAR struct socket *newsock)
 {
 #warning Missing logic
   return -EOPNOTSUPP;
@@ -570,7 +571,7 @@ static int can_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
  ****************************************************************************/
 
 static int can_poll_local(FAR struct socket *psock, FAR struct pollfd *fds,
-                        bool setup)
+                          bool setup)
 {
   FAR struct can_conn_s *conn;
   FAR struct can_poll_s *info;
@@ -580,18 +581,17 @@ static int can_poll_local(FAR struct socket *psock, FAR struct pollfd *fds,
   DEBUGASSERT(psock != NULL && psock->s_conn != NULL);
   conn = (FAR struct can_conn_s *)psock->s_conn;
   info = conn->pollinfo;
-  
-  //FIXME add NETDEV_DOWN support
+
+  /* FIXME add NETDEV_DOWN support */
 
   /* Check if we are setting up or tearing down the poll */
 
   if (setup)
     {
-        
       net_lock();
-      
+
       info->dev = conn->dev;
-      
+
       cb = can_callback_alloc(info->dev, conn);
       if (cb == NULL)
         {
@@ -600,82 +600,84 @@ static int can_poll_local(FAR struct socket *psock, FAR struct pollfd *fds,
         }
 
       /* Initialize the poll info container */
-    
+
       info->psock  = psock;
       info->fds    = fds;
       info->cb     = cb;
-    
+
       /* Initialize the callback structure.  Save the reference to the info
        * structure as callback private data so that it will be available during
        * callback processing.
        */
-    
+
       cb->flags    = NETDEV_DOWN;
       cb->priv     = (FAR void *)info;
       cb->event    = can_poll_eventhandler;
-    
+
       if ((fds->events & POLLOUT) != 0)
         {
           cb->flags |= CAN_POLL;
         }
-    
+
       if ((fds->events & POLLIN) != 0)
         {
           cb->flags |= CAN_NEWDATA;
         }
-    
+
       /* Save the reference in the poll info structure as fds private as well
        * for use during poll teardown as well.
        */
-    
+
       fds->priv = (FAR void *)info;
-    
+
       /* Check for read data availability now */
-    
+
       if (!IOB_QEMPTY(&conn->readahead))
         {
           /* Normal data may be read without blocking. */
-    
+
           fds->revents |= (POLLRDNORM & fds->events);
         }
-    
+
     #if 0
       if (psock_udp_cansend(psock) >= 0)
         {
           /* Normal data may be sent without blocking (at least one byte). */
-    
+
           fds->revents |= (POLLWRNORM & fds->events);
         }
     #endif
-    
+
       /* Check if any requested events are already in effect */
-    
+
       if (fds->revents != 0)
         {
           /* Yes.. then signal the poll logic */
+
           nxsem_post(fds->sem);
         }
-    
+
 errout_with_lock:
       net_unlock();
     }
-  else 
+  else
     {
       info = (FAR struct can_poll_s *)fds->priv;
-        
+
       if (info != NULL)
-      {
-        /* Cancel any response notifications */      
-        can_callback_free(info->dev, conn, info->cb);
+        {
+          /* Cancel any response notifications */
+
+          can_callback_free(info->dev, conn, info->cb);
 
-        /* Release the poll/select data slot */
+          /* Release the poll/select data slot */
 
-        info->fds->priv = NULL;
+          info->fds->priv = NULL;
 
-        /* Then free the poll info container */
+          /* Then free the poll info container */
 
-        info->psock = NULL;
-      }
+          info->psock = NULL;
+        }
     }
 
   return ret;
@@ -702,27 +704,28 @@ errout_with_lock:
  ****************************************************************************/
 
 static ssize_t can_send(FAR struct socket *psock, FAR const void *buf,
-                            size_t len, int flags)
+                        size_t len, int flags)
 {
-	  ssize_t ret;
+  ssize_t ret;
 
-	  /* Only SOCK_RAW is supported */
+  /* Only SOCK_RAW is supported */
 
-	  if (psock->s_type == SOCK_RAW)
-	    {
-	      /* Raw packet send */
-	      ret = psock_can_send(psock, buf, len);
-	    }
-	  else
-	    {
-	      /* EDESTADDRREQ.  Signifies that the socket is not connection-mode and
-	       * no peer address is set.
-	       */
+  if (psock->s_type == SOCK_RAW)
+    {
+      /* Raw packet send */
 
-	      ret = -EDESTADDRREQ;
-	    }
+      ret = psock_can_send(psock, buf, len);
+    }
+  else
+    {
+      /* EDESTADDRREQ.  Signifies that the socket is not connection-mode and
+       * no peer address is set.
+       */
+
+      ret = -EDESTADDRREQ;
+    }
 
-	  return ret;
+  return ret;
 }
 
 /****************************************************************************
@@ -750,11 +753,11 @@ static ssize_t can_send(FAR struct socket *psock, FAR const void *buf,
  ****************************************************************************/
 
 static ssize_t can_sendto(FAR struct socket *psock, FAR const void *buf,
-                              size_t len, int flags,
-                              FAR const struct sockaddr *to, socklen_t tolen)
+                          size_t len, int flags,
+                          FAR const struct sockaddr *to, socklen_t tolen)
 {
-   nerr("ERROR: sendto() not supported for raw packet sockets\n");
-   return -EAFNOSUPPORT;
+  nerr("ERROR: sendto() not supported for raw packet sockets\n");
+  return -EAFNOSUPPORT;
 }
 
 /****************************************************************************
diff --git a/net/socket/getsockopt.c b/net/socket/getsockopt.c
index bc07a03..6d71106 100644
--- a/net/socket/getsockopt.c
+++ b/net/socket/getsockopt.c
@@ -376,7 +376,7 @@ int psock_getsockopt(FAR struct socket *psock, int level, int option,
        ret = can_getsockopt(psock, option, value, value_len);
 #endif
        break;
-       
+
       /* These levels are defined in sys/socket.h, but are not yet
        * implemented.
        */


[incubator-nuttx] 07/31: Added basic poll()/select support

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch SocketCAN
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 24d8699ad8eb5096fb1a321da8e4c09c42473d55
Author: Peter van der Perk <pe...@nxp.com>
AuthorDate: Fri Feb 21 16:24:54 2020 +0100

    Added basic poll()/select support
    
    Futhermore addded stubs for SocketCAN sockopts
---
 include/netpacket/can.h                      |  18 +++
 include/nuttx/can.h                          |  41 +++++
 include/nuttx/mm/iob.h                       |   3 +
 include/nuttx/wqueue.h                       |   3 +-
 include/sys/socket.h                         |  10 ++
 net/can/Kconfig                              |  19 +++
 net/can/Make.defs                            |   8 +
 net/can/can.h                                |  96 ++++++++++--
 net/can/can_callback.c                       | 145 +++++++++++++++++-
 net/can/can_conn.c                           |  22 +--
 net/can/can_getsockopt.c                     | 154 +++++++++++++++++++
 net/can/{can_callback.c => can_notifier.c}   |  50 +++----
 net/can/can_poll.c                           |   2 +-
 net/can/can_recvfrom.c                       | 166 +++++++++++++++++++-
 net/can/{can_callback.c => can_setsockopt.c} | 102 ++++++++++---
 net/can/can_sockif.c                         | 216 ++++++++++++++++++---------
 net/socket/Kconfig                           |   6 +
 net/socket/getsockopt.c                      |   6 +
 18 files changed, 909 insertions(+), 158 deletions(-)

diff --git a/include/netpacket/can.h b/include/netpacket/can.h
index b93bb21..45edab5 100644
--- a/include/netpacket/can.h
+++ b/include/netpacket/can.h
@@ -47,6 +47,9 @@
 #define CAN_EFF_MASK 0x1fffffff  /* Extended frame format (EFF) */
 #define CAN_ERR_MASK 0x1fffffff  /* Omit EFF, RTR, ERR flags */
 
+#define CAN_MTU		(sizeof(struct can_frame))
+#define CANFD_MTU	(sizeof(struct canfd_frame))
+
 /* PF_CAN protocols */
 
 #define CAN_RAW      1           /* RAW sockets */
@@ -58,6 +61,21 @@
 #define CAN_J1939    7           /* SAE J1939 */
 #define CAN_NPROTO   8
 
+/* CAN_RAW socket options */
+
+#define CAN_RAW_FILTER         (__SO_PROTOCOL + 0)     
+                                 /* set 0 .. n can_filter(s) */
+#define CAN_RAW_ERR_FILTER     (__SO_PROTOCOL + 1)      
+                                 /* set filter for error frames */
+#define CAN_RAW_LOOPBACK       (__SO_PROTOCOL + 2)      
+                                 /* local loopback (default:on) */
+#define CAN_RAW_RECV_OWN_MSGS  (__SO_PROTOCOL + 3)	     
+                                 /* receive my own msgs (default:off) */
+#define CAN_RAW_FD_FRAMES      (__SO_PROTOCOL + 4)      
+                                 /* allow CAN FD frames (default:off) */
+#define CAN_RAW_JOIN_FILTERS   (__SO_PROTOCOL + 5)     
+                                 /* all filters must match to trigger */
+
 /****************************************************************************
  * Public Types
  ****************************************************************************/
diff --git a/include/nuttx/can.h b/include/nuttx/can.h
index fd86b74..02f80a8 100644
--- a/include/nuttx/can.h
+++ b/include/nuttx/can.h
@@ -45,6 +45,8 @@
 #  include <nuttx/wqueue.h>
 #endif
 
+#include <queue.h>
+
 #ifdef CONFIG_NET_CAN
 
 /************************************************************************************
@@ -187,8 +189,26 @@
  * Public Types
  ************************************************************************************/
 
+typedef FAR void *CAN_HANDLE;
+
+struct can_response_s
+{
+  sq_entry_t flink;
+
+  /* Message-specific data may follow */
+}; //FIXME remvoe
+
+
 typedef uint32_t canid_t;
 
+/*
+ * Controller Area Network Error Message Frame Mask structure
+ *
+ * bit 0-28	: error class mask (see include/uapi/linux/can/error.h)
+ * bit 29-31	: set to zero
+ */
+typedef uint32_t can_err_mask_t;
+
 /* CAN payload length and DLC definitions according to ISO 11898-1 */
 #define CAN_MAX_DLC 8
 #define CAN_MAX_DLEN 8
@@ -256,6 +276,27 @@ struct canfd_frame {
 };
 
 
+/**
+ * struct can_filter - CAN ID based filter in can_register().
+ * @can_id:   relevant bits of CAN ID which are not masked out.
+ * @can_mask: CAN mask (see description)
+ *
+ * Description:
+ * A filter matches, when
+ *
+ *          <received_can_id> & mask == can_id & mask
+ *
+ * The filter can be inverted (CAN_INV_FILTER bit set in can_id) or it can
+ * filter for error message frames (CAN_ERR_FLAG bit set in mask).
+ */
+struct can_filter {
+	canid_t can_id;
+	canid_t can_mask;
+};
+
+#define CAN_INV_FILTER 0x20000000U /* to be set in can_filter.can_id */
+#define CAN_RAW_FILTER_MAX 512 /* maximum number of can_filter set via setsockopt() */
+
 /************************************************************************************
  * Public Function Prototypes
  ************************************************************************************/
diff --git a/include/nuttx/mm/iob.h b/include/nuttx/mm/iob.h
index 8984af6..cabd2ff 100644
--- a/include/nuttx/mm/iob.h
+++ b/include/nuttx/mm/iob.h
@@ -220,6 +220,9 @@ enum iob_user_e
 #ifdef CONFIG_WIRELESS_BLUETOOTH
   IOBUSER_WIRELESS_BLUETOOTH,
 #endif
+#if defined(CONFIG_NET_CAN)
+  IOBUSER_NET_CAN_READAHEAD,
+#endif
   IOBUSER_GLOBAL,
   IOBUSER_NENTRIES /* MUST BE LAST ENTRY */
 };
diff --git a/include/nuttx/wqueue.h b/include/nuttx/wqueue.h
index d353772..5ea8dfc 100644
--- a/include/nuttx/wqueue.h
+++ b/include/nuttx/wqueue.h
@@ -280,7 +280,8 @@ enum work_evtype_e
   WORK_TCP_DISCONNECT,   /* Notify loss of TCP connection */
   WORK_UDP_READAHEAD,    /* Notify that UDP read-ahead data is available */
   WORK_UDP_WRITEBUFFER,  /* Notify that UDP write buffer is empty */
-  WORK_NETLINK_RESPONSE  /* Notify that Netlink response is available */
+  WORK_NETLINK_RESPONSE, /* Notify thtat Netlink response is available */
+  WORK_CAN_READAHEAD     /* Notify that CAN read-ahead data is available */
 };
 
 /* This structure describes one notification and is provided as input to
diff --git a/include/sys/socket.h b/include/sys/socket.h
index e85242e..bc7cd26 100644
--- a/include/sys/socket.h
+++ b/include/sys/socket.h
@@ -202,6 +202,15 @@
                             * return: int
                             */
 
+                            
+/* The options are unsupported but included for compatibility
+ * and portability
+ */
+#define SO_TIMESTAMP    29
+#define SO_SNDBUFFORCE	32 
+#define SO_RCVBUFFORCE	33 
+#define SO_RXQ_OVFL     40
+
 /* Protocol-level socket operations. */
 
 #define SOL_IP          1 /* See options in include/netinet/ip.h */
@@ -212,6 +221,7 @@
 #define SOL_L2CAP       6 /* See options in include/netpacket/bluetooth.h */
 #define SOL_SCO         7 /* See options in include/netpacket/bluetooth.h */
 #define SOL_RFCOMM      8 /* See options in include/netpacket/bluetooth.h */
+#define SOL_CAN_RAW     9 /* See options in include/netpacket/can.h */
 
 /* Protocol-level socket options may begin with this value */
 
diff --git a/net/can/Kconfig b/net/can/Kconfig
index 2ae1f7b..2272db7 100644
--- a/net/can/Kconfig
+++ b/net/can/Kconfig
@@ -21,6 +21,25 @@ config CAN_CONNS
 	default 4
 	---help---
 		Maximum number of CAN connections (all tasks).
+		
+config NET_CAN_SOCK_OPTS
+	bool "sockopt support"
+	default n
+	select NET_CANPROTO_OPTIONS
+	---help---
+		Enable support for the CAN socket options
+		
+config NET_CAN_NOTIFIER
+	bool "Support CAN notifications"
+	default n
+	depends on SCHED_WORKQUEUE
+	select WQUEUE_NOTIFIER
+	---help---
+		Enable building of CAN notifier logic that will execute a worker
+		function on the low priority work queue when read-ahead data
+		is available or when a CAN connection is lost.  This is is a general
+		purpose notifier, but was developed specifically to support poll()
+		logic where the poll must wait for these events.
 
 endif # NET_CAN
 endmenu # CAN Socket Support
diff --git a/net/can/Make.defs b/net/can/Make.defs
index d078a05..3204b3b 100644
--- a/net/can/Make.defs
+++ b/net/can/Make.defs
@@ -28,6 +28,14 @@ SOCK_CSRCS += can_sockif.c
 SOCK_CSRCS += can_send.c
 SOCK_CSRCS += can_recvfrom.c
 
+ifeq ($(CONFIG_NET_CAN_NOTIFIER),y)
+SOCK_CSRCS += can_notifier.c
+endif
+
+ifeq ($(CONFIG_NET_CANPROTO_OPTIONS),y)
+SOCK_CSRCS += can_setsockopt.c can_getsockopt.c
+endif
+
 NET_CSRCS += can_conn.c
 NET_CSRCS += can_input.c
 NET_CSRCS += can_callback.c
diff --git a/net/can/can.h b/net/can/can.h
index c2b6857..46c7425 100644
--- a/net/can/can.h
+++ b/net/can/can.h
@@ -32,11 +32,16 @@
 
 #include <netpacket/can.h>
 #include <nuttx/semaphore.h>
+#include <nuttx/can.h>
 #include <nuttx/net/netdev.h>
 
 #include "devif/devif.h"
 #include "socket/socket.h"
 
+#ifdef CONFIG_NET_CAN_NOTIFIER
+#  include <nuttx/wqueue.h>
+#endif
+
 #ifdef CONFIG_NET_CAN
 
 /****************************************************************************
@@ -54,6 +59,16 @@
  * Public Type Definitions
  ****************************************************************************/
 
+/* This is a container that holds the poll-related information */
+
+struct can_poll_s
+{
+  FAR struct socket *psock;        /* Needed to handle loss of connection */
+  FAR struct net_driver_s *dev;    /* Needed to free the callback structure */
+  struct pollfd *fds;              /* Needed to handle poll events */
+  FAR struct devif_callback_s *cb; /* Needed to teardown the poll */
+};
+
 /* This "connection" structure describes the underlying state of the socket. */
 
 struct can_conn_s
@@ -70,16 +85,26 @@ struct can_conn_s
   FAR struct devif_callback_s *list; /* NetLink callbacks */
 
   FAR struct net_driver_s *dev;      /* Reference to CAN device */
+  
+  /* Read-ahead buffering.
+   *
+   *   readahead - A singly linked list of type struct iob_qentry_s
+   *               where the CAN/IP read-ahead data is retained.
+   */
+
+  struct iob_queue_s readahead;   /* remove Read-ahead buffering */
 
   /* CAN-specific content follows */
 
   uint8_t protocol;                  /* Selected CAN protocol */
   int16_t crefs;                     /* Reference count */
+  
 
-  /* poll() support */
+  /* The following is a list of poll structures of threads waiting for
+   * socket events.
+   */
 
-  FAR sem_t *pollsem;                /* Used to wakeup poll() */
-  FAR pollevent_t *pollevent;        /* poll() wakeup event */
+  struct can_poll_s pollinfo[4]; //FIXME make dynamic
 };
 
 /****************************************************************************
@@ -166,6 +191,35 @@ uint16_t can_callback(FAR struct net_driver_s *dev,
                       FAR struct can_conn_s *conn, uint16_t flags);
 
 /****************************************************************************
+ * Name: can_datahandler
+ *
+ * Description:
+ *   Handle data that is not accepted by the application.  This may be called
+ *   either (1) from the data receive logic if it cannot buffer the data, or
+ *   (2) from the CAN event logic is there is no listener in place ready to
+ *   receive the data.
+ *
+ * Input Parameters:
+ *   conn - A pointer to the CAN connection structure
+ *   buffer - A pointer to the buffer to be copied to the read-ahead
+ *     buffers
+ *   buflen - The number of bytes to copy to the read-ahead buffer.
+ *
+ * Returned Value:
+ *   The number of bytes actually buffered is returned.  This will be either
+ *   zero or equal to buflen; partial packets are not buffered.
+ *
+ * Assumptions:
+ * - The caller has checked that CAN_NEWDATA is set in flags and that is no
+ *   other handler available to process the incoming data.
+ * - Called from network stack logic with the network stack locked
+ *
+ ****************************************************************************/
+
+uint16_t can_datahandler(FAR struct can_conn_s *conn, FAR uint8_t *buffer,
+                         uint16_t buflen);
+
+/****************************************************************************
  * Name: can_recvfrom
  *
  * Description:
@@ -214,17 +268,6 @@ ssize_t can_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
 void can_poll(FAR struct net_driver_s *dev, FAR struct can_conn_s *conn);
 
 /****************************************************************************
- * Name: can_active()
- *
- * Description:
- *   Find a connection structure that is the appropriate connection for the
- *   provided NetLink address
- *
- ****************************************************************************/
-
-FAR struct can_conn_s *can_active(FAR struct sockaddr_can *addr);
-
-/****************************************************************************
  * Name: psock_can_send
  *
  * Description:
@@ -247,6 +290,31 @@ struct socket;
 ssize_t psock_can_send(FAR struct socket *psock, FAR const void *buf,
                        size_t len);
 
+/****************************************************************************
+ * Name: can_readahead_signal
+ *
+ * Description:
+ *   Read-ahead data has been buffered.  Signal all threads waiting for
+ *   read-ahead data to become available.
+ *
+ *   When read-ahead data becomes available, *all* of the workers waiting
+ *   for read-ahead data will be executed.  If there are multiple workers
+ *   waiting for read-ahead data then only the first to execute will get the
+ *   data.  Others will need to call can_readahead_notifier_setup() once
+ *   again.
+ *
+ * Input Parameters:
+ *   conn  - The CAN connection where read-ahead data was just buffered.
+ *
+ * Returned Value:
+ *   None.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_CAN_NOTIFIER
+void can_readahead_signal(FAR struct can_conn_s *conn);
+#endif
+
 
 #undef EXTERN
 #ifdef __cplusplus
diff --git a/net/can/can_callback.c b/net/can/can_callback.c
index 2fad951..6f3ae93 100644
--- a/net/can/can_callback.c
+++ b/net/can/can_callback.c
@@ -50,6 +50,61 @@
 #include "can/can.h"
 
 /****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: can_data_event
+ *
+ * Description:
+ *   Handle data that is not accepted by the application because there is no
+ *   listener in place ready to receive the data.
+ *
+ * Assumptions:
+ * - The caller has checked that CAN_NEWDATA is set in flags and that is no
+ *   other handler available to process the incoming data.
+ * - This function must be called with the network locked.
+ *
+ ****************************************************************************/
+
+static inline uint16_t
+can_data_event(FAR struct net_driver_s *dev, FAR struct can_conn_s *conn,
+               uint16_t flags)
+{
+  uint16_t ret;
+  uint8_t *buffer = dev->d_appdata;
+  int      buflen = dev->d_len;
+  uint16_t recvlen;
+
+  ret = (flags & ~CAN_NEWDATA);
+
+  //ninfo("No listener on connection\n");
+
+   /* Save as the packet data as in the read-ahead buffer.  NOTE that
+    * partial packets will not be buffered.
+    */
+
+  recvlen = can_datahandler(conn, buffer, buflen);
+  if (recvlen < buflen)
+    {
+      /* There is no handler to receive new data and there are no free
+       * read-ahead buffers to retain the data -- drop the packet.
+       */
+
+      ninfo("Dropped %d bytes\n", dev->d_len);
+
+#ifdef CONFIG_NET_STATISTICS
+      //g_netstats.tcp.drop++;
+#endif
+    }
+        
+  /* In any event, the new data has now been handled */
+
+  dev->d_len = 0;
+  return ret;
+}
+
+/****************************************************************************
  * Public Functions
  ****************************************************************************/
 
@@ -77,9 +132,97 @@ uint16_t can_callback(FAR struct net_driver_s *dev,
       /* Perform the callback */
 
       flags = devif_conn_event(dev, conn, flags, conn->list);
-    }
+    
+    if ((flags & CAN_NEWDATA) != 0)
+      {
+        /* Data was not handled.. dispose of it appropriately */
 
+        flags = can_data_event(dev, conn, flags);
+      }
+  }
+  
   return flags;
 }
 
+/****************************************************************************
+ * Name: can_datahandler
+ *
+ * Description:
+ *   Handle data that is not accepted by the application.  This may be called
+ *   either (1) from the data receive logic if it cannot buffer the data, or
+ *   (2) from the CAN event logic is there is no listener in place ready to
+ *   receive the data.
+ *
+ * Input Parameters:
+ *   conn - A pointer to the CAN connection structure
+ *   buffer - A pointer to the buffer to be copied to the read-ahead
+ *     buffers
+ *   buflen - The number of bytes to copy to the read-ahead buffer.
+ *
+ * Returned Value:
+ *   The number of bytes actually buffered is returned.  This will be either
+ *   zero or equal to buflen; partial packets are not buffered.
+ *
+ * Assumptions:
+ * - The caller has checked that CAN_NEWDATA is set in flags and that is no
+ *   other handler available to process the incoming data.
+ * - This function must be called with the network locked.
+ *
+ ****************************************************************************/
+
+uint16_t can_datahandler(FAR struct can_conn_s *conn, FAR uint8_t *buffer,
+                         uint16_t buflen)
+{
+  FAR struct iob_s *iob;
+  int ret;
+
+  /* Try to allocate on I/O buffer to start the chain without waiting (and
+   * throttling as necessary).  If we would have to wait, then drop the
+   * packet.
+   */
+
+  iob = iob_tryalloc(true, IOBUSER_NET_CAN_READAHEAD);
+  if (iob == NULL)
+    {
+      nerr("ERROR: Failed to create new I/O buffer chain\n");
+      return 0;
+    }
+
+  /* Copy the new appdata into the I/O buffer chain (without waiting) */
+
+  ret = iob_trycopyin(iob, buffer, buflen, 0, true,
+                      IOBUSER_NET_CAN_READAHEAD);
+  if (ret < 0)
+    {
+      /* On a failure, iob_copyin return a negated error value but does
+       * not free any I/O buffers.
+       */
+
+      nerr("ERROR: Failed to add data to the I/O buffer chain: %d\n", ret);
+      iob_free_chain(iob, IOBUSER_NET_CAN_READAHEAD);
+      return 0;
+    }
+
+  /* Add the new I/O buffer chain to the tail of the read-ahead queue (again
+   * without waiting).
+   */
+
+  ret = iob_tryadd_queue(iob, &conn->readahead);
+  if (ret < 0)
+    {
+      nerr("ERROR: Failed to queue the I/O buffer chain: %d\n", ret);
+      iob_free_chain(iob, IOBUSER_NET_TCP_READAHEAD);
+      return 0;
+    }
+    
+#ifdef CONFIG_NET_CAN_NOTIFIER
+  /* Provide notification(s) that additional CAN read-ahead data is
+   * available.
+   */
+
+  can_readahead_signal(conn);
+#endif
+  return buflen;
+}
+
 #endif /* CONFIG_NET && CONFIG_NET_CAN */
diff --git a/net/can/can_conn.c b/net/can/can_conn.c
index 77733b3..4969f6d 100644
--- a/net/can/can_conn.c
+++ b/net/can/can_conn.c
@@ -81,6 +81,7 @@ static void _can_semgive(FAR sem_t *sem)
 {
   nxsem_post(sem);
 }
+
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
@@ -201,25 +202,4 @@ FAR struct can_conn_s *can_nextconn(FAR struct can_conn_s *conn)
     }
 }
 
-/****************************************************************************
- * Name: can_active
- *
- * Description:
- *   Find a connection structure that is the appropriate connection for the
- *   provided NetLink address
- *
- * Assumptions:
- *
- ****************************************************************************/
-
-FAR struct can_conn_s *can_active(FAR struct sockaddr_can *addr)
-{
-  /* This function is used to handle routing of incoming messages to sockets
-   * connected to the address.  There is no such use case for NetLink
-   * sockets.
-   */
-
-  return NULL;
-}
-
 #endif /* CONFIG_NET_CAN */
diff --git a/net/can/can_getsockopt.c b/net/can/can_getsockopt.c
new file mode 100644
index 0000000..d9e19f8
--- /dev/null
+++ b/net/can/can_getsockopt.c
@@ -0,0 +1,154 @@
+/****************************************************************************
+ * net/can/can_setsockopt.c
+ *
+ *   Copyright (C) 2018 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <gn...@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/time.h>
+#include <stdint.h>
+#include <errno.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <netpacket/can.h>
+
+#include <nuttx/net/net.h>
+#include <nuttx/net/can.h>
+
+#include "socket/socket.h"
+#include "utils/utils.h"
+#include "can/can.h"
+
+#ifdef CONFIG_NET_CANPROTO_OPTIONS
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: can_getsockopt
+ *
+ * Description:
+ *   can_getsockopt() retrieves the value for the option specified by the
+ *   'option' argument for the socket specified by the 'psock' argument.  If
+ *   the size of the option value is greater than 'value_len', the value
+ *   stored in the object pointed to by the 'value' argument will be silently
+ *   truncated. Otherwise, the length pointed to by the 'value_len' argument
+ *   will be modified to indicate the actual length of the 'value'.
+ *
+ *   See <sys/socket.h> a complete list of values for the socket-level
+ *   'option' argument.  Protocol-specific options are are protocol specific
+ *   header files (such as netpacket/can.h for the case of the CAN protocol).
+ *
+ * Input Parameters:
+ *   psock     Socket structure of the socket to query
+ *   level     Protocol level to set the option
+ *   option    identifies the option to get
+ *   value     Points to the argument value
+ *   value_len The length of the argument value
+ *
+ * Returned Value:
+ *   Returns zero (OK) on success.  On failure, it returns a negated errno
+ *   value to indicate the nature of the error.  See psock_getsockopt() for
+ *   the complete list of appropriate return error codes.
+ *
+ ****************************************************************************/
+
+int can_getsockopt  (FAR struct socket *psock, int option,
+                   FAR void *value, FAR socklen_t *value_len)
+{
+
+  FAR struct can_conn_s *conn;
+  int ret;
+  int count = 0;
+
+  DEBUGASSERT(psock != NULL && value != NULL && value_len != NULL &&
+              psock->s_conn != NULL);
+  conn = (FAR struct can_conn_s *)psock->s_conn;
+
+  if (psock->s_type != SOCK_RAW)
+    {
+      nerr("ERROR:  Not a RAW CAN socket\n");
+      return -ENOTCONN;
+    }
+
+
+  switch (option)
+    {
+      
+      case CAN_RAW_FILTER:
+        if (*value_len % sizeof(struct can_filter) != 0)
+        {
+		  ret = -EINVAL;
+        }
+        
+        if (value_len > CAN_RAW_FILTER_MAX * sizeof(struct can_filter))
+        {
+		  ret = -EINVAL;
+        }
+
+		count = *value_len / sizeof(struct can_filter);
+        
+        /* FIXME pass filter to driver */
+        break;
+      
+      case CAN_RAW_ERR_FILTER:
+        break;
+      
+      case CAN_RAW_LOOPBACK:
+        break;
+      
+      case CAN_RAW_RECV_OWN_MSGS:
+        break;
+      
+      case CAN_RAW_FD_FRAMES:
+        break;
+      
+      case CAN_RAW_JOIN_FILTERS:
+        break;
+
+      default:
+        nerr("ERROR: Unrecognized RAW CAN socket option: %d\n", option);
+        ret = -ENOPROTOOPT;
+        break;
+    }
+
+  return ret;
+}
+
+#endif /* CONFIG_NET_CANPROTO_OPTIONS */
diff --git a/net/can/can_callback.c b/net/can/can_notifier.c
similarity index 70%
copy from net/can/can_callback.c
copy to net/can/can_notifier.c
index 2fad951..ffb4878 100644
--- a/net/can/can_callback.c
+++ b/net/can/can_notifier.c
@@ -1,7 +1,7 @@
 /****************************************************************************
- * net/pkt/pkt_callback.c
+ * net/can/can_notifier.c
  *
- *   Copyright (C) 2014 Gregory Nutt. All rights reserved.
+ *   Copyright (C) 2018 Gregory Nutt. All rights reserved.
  *   Author: Gregory Nutt <gn...@nuttx.org>
  *
  * Redistribution and use in source and binary forms, with or without
@@ -38,48 +38,46 @@
  ****************************************************************************/
 
 #include <nuttx/config.h>
-#if defined(CONFIG_NET) && defined(CONFIG_NET_CAN)
 
-#include <stdint.h>
-#include <debug.h>
+#include <sys/types.h>
+#include <assert.h>
 
-#include <nuttx/net/netconfig.h>
-#include <nuttx/net/netdev.h>
+#include <nuttx/wqueue.h>
 
-#include "devif/devif.h"
 #include "can/can.h"
 
+#ifdef CONFIG_NET_CAN_NOTIFIER
+
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
 
 /****************************************************************************
- * Name: can_callback
+ * Name: can_readahead_signal
  *
  * Description:
- *   Inform the application holding the packet socket of a change in state.
+ *   Read-ahead data has been buffered.  Signal all threads waiting for
+ *   read-ahead data to become available.
  *
- * Returned Value:
- *   OK if packet has been processed, otherwise ERROR.
+ *   When read-ahead data becomes available, *all* of the workers waiting
+ *   for read-ahead data will be executed.  If there are multiple workers
+ *   waiting for read-ahead data then only the first to execute will get the
+ *   data.  Others will need to call can_readahead_notifier_setup() once
+ *   again.
+ *
+ * Input Parameters:
+ *   conn  - The CAN connection where read-ahead data was just buffered.
  *
- * Assumptions:
- *   This function is called with the network locked.
+ * Returned Value:
+ *   None.
  *
  ****************************************************************************/
 
-uint16_t can_callback(FAR struct net_driver_s *dev,
-                      FAR struct can_conn_s *conn, uint16_t flags)
+void can_readahead_signal(FAR struct can_conn_s *conn)
 {
-  /* Some sanity checking */
-
-  if (conn)
-    {
-      /* Perform the callback */
-
-      flags = devif_conn_event(dev, conn, flags, conn->list);
-    }
+  /* This is just a simple wrapper around work_notifier_signal(). */
 
-  return flags;
+  work_notifier_signal(WORK_CAN_READAHEAD, conn);
 }
 
-#endif /* CONFIG_NET && CONFIG_NET_CAN */
+#endif /* CONFIG_NET_TCP_NOTIFIER */
diff --git a/net/can/can_poll.c b/net/can/can_poll.c
index 84aeeab..80e59a2 100644
--- a/net/can/can_poll.c
+++ b/net/can/can_poll.c
@@ -88,13 +88,13 @@ void can_poll(FAR struct net_driver_s *dev, FAR struct can_conn_s *conn)
       dev->d_sndlen  = 0;
 
       /* Perform the application callback */
-
       can_callback(dev, conn, CAN_POLL);
 
       /* Check if the application has data to send */
 
       if (dev->d_sndlen > 0)
         {
+            //FIXME missing logic
           return;
         }
     }
diff --git a/net/can/can_recvfrom.c b/net/can/can_recvfrom.c
index 4062ed3..990786d 100644
--- a/net/can/can_recvfrom.c
+++ b/net/can/can_recvfrom.c
@@ -68,6 +68,7 @@
 
 struct can_recvfrom_s
 {
+  FAR struct socket       *pr_sock;      /* The parent socket structure */
   FAR struct devif_callback_s *pr_cb;  /* Reference to callback instance */
   sem_t        pr_sem;                 /* Semaphore signals recv completion */
   size_t       pr_buflen;              /* Length of receive buffer */
@@ -128,7 +129,7 @@ static inline void can_add_recvlen(FAR struct can_recvfrom_s *pstate,
  *
  ****************************************************************************/
 
-static void can_recvfrom_newdata(FAR struct net_driver_s *dev,
+static size_t can_recvfrom_newdata(FAR struct net_driver_s *dev,
                                  FAR struct can_recvfrom_s *pstate)
 {
   size_t recvlen;
@@ -150,6 +151,150 @@ static void can_recvfrom_newdata(FAR struct net_driver_s *dev,
   /* Update the accumulated size of the data read */
 
   can_add_recvlen(pstate, recvlen);
+
+  return recvlen;
+}
+
+
+/****************************************************************************
+ * Name: can_newdata
+ *
+ * Description:
+ *   Copy the read data from the packet
+ *
+ * Input Parameters:
+ *   dev      The structure of the network driver that generated the event
+ *   pstate   recvfrom state structure
+ *
+ * Returned Value:
+ *   None.
+ *
+ * Assumptions:
+ *   The network is locked.
+ *
+ ****************************************************************************/
+
+static inline void can_newdata(FAR struct net_driver_s *dev,
+                               FAR struct can_recvfrom_s *pstate)
+{
+  /* Take as much data from the packet as we can */
+
+  size_t recvlen = can_recvfrom_newdata(dev, pstate);
+
+  /* If there is more data left in the packet that we could not buffer, then
+   * add it to the read-ahead buffers.
+   */
+
+  if (recvlen < dev->d_len)
+    {
+      FAR struct can_conn_s *conn = (FAR struct can_conn_s *)pstate->pr_sock->s_conn;
+      FAR uint8_t *buffer = (FAR uint8_t *)dev->d_appdata + recvlen;
+      uint16_t buflen = dev->d_len - recvlen;
+#ifdef CONFIG_DEBUG_NET
+      uint16_t nsaved;
+
+      nsaved = can_datahandler(conn, buffer, buflen);
+#else
+      can_datahandler(conn, buffer, buflen);
+#endif
+
+      /* There are complicated buffering issues that are not addressed fully
+       * here.  For example, what if up_datahandler() cannot buffer the
+       * remainder of the packet?  In that case, the data will be dropped but
+       * still ACKed.  Therefore it would not be resent.
+       *
+       * This is probably not an issue here because we only get here if the
+       * read-ahead buffers are empty and there would have to be something
+       * serioulsy wrong with the configuration not to be able to buffer a
+       * partial packet in this context.
+       */
+
+#ifdef CONFIG_DEBUG_NET
+      if (nsaved < buflen)
+        {
+          nerr("ERROR: packet data not saved (%d bytes)\n", buflen - nsaved);
+        }
+#endif
+    }
+
+  /* Indicate no data in the buffer */
+
+  dev->d_len = 0;
+}
+
+/****************************************************************************
+ * Name: can_readahead
+ *
+ * Description:
+ *   Copy the read-ahead data from the packet
+ *
+ * Input Parameters:
+ *   pstate   recvfrom state structure
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *   The network is locked.
+ *
+ ****************************************************************************/
+
+static inline int can_readahead(struct can_recvfrom_s *pstate)
+{
+  FAR struct can_conn_s *conn = (FAR struct can_conn_s *)pstate->pr_sock->s_conn;
+  FAR struct iob_s *iob;
+  int recvlen;
+
+  /* Check there is any CAN data already buffered in a read-ahead
+   * buffer.
+   */
+
+  if((iob = iob_peek_queue(&conn->readahead)) != NULL &&
+          pstate->pr_buflen > 0)
+    {
+      DEBUGASSERT(iob->io_pktlen > 0);
+
+      /* Transfer that buffered data from the I/O buffer chain into
+       * the user buffer.
+       */
+
+      recvlen = iob_copyout(pstate->pr_buffer, iob, pstate->pr_buflen, 0);
+
+      /* If we took all of the data from the I/O buffer chain is empty, then
+       * release it.  If there is still data available in the I/O buffer
+       * chain, then just trim the data that we have taken from the
+       * beginning of the I/O buffer chain.
+       */
+
+      if (recvlen >= iob->io_pktlen)
+        {
+          FAR struct iob_s *tmp;
+
+          /* Remove the I/O buffer chain from the head of the read-ahead
+           * buffer queue.
+           */
+
+          tmp = iob_remove_queue(&conn->readahead);
+          DEBUGASSERT(tmp == iob);
+          UNUSED(tmp);
+
+          /* And free the I/O buffer chain */
+
+          iob_free_chain(iob, IOBUSER_NET_CAN_READAHEAD);
+        }
+      else
+        {
+          /* The bytes that we have received from the head of the I/O
+           * buffer chain (probably changing the head of the I/O
+           * buffer queue).
+           */
+
+          iob_trimhead_queue(&conn->readahead, recvlen,
+                             IOBUSER_NET_CAN_READAHEAD);
+        }
+        return recvlen;
+    }
+    return 0;
 }
 
 static uint16_t can_recvfrom_eventhandler(FAR struct net_driver_s *dev,
@@ -170,7 +315,7 @@ static uint16_t can_recvfrom_eventhandler(FAR struct net_driver_s *dev,
         {
           /* Copy the packet */
 
-          can_recvfrom_newdata(dev, pstate);
+          can_newdata(dev, pstate);
 
           /* We are finished. */
 
@@ -228,7 +373,7 @@ static ssize_t can_recvfrom_result(int result,
   if (pstate->pr_result < 0)
     {
       /* This might return EAGAIN on a timeout or ENOTCONN on loss of
-       * connection (TCP only)
+       * connection (CAN only)
        */
 
       return pstate->pr_result;
@@ -307,6 +452,19 @@ ssize_t can_recvfrom(FAR struct socket *psock, FAR void *buf,
 
   state.pr_buflen = len;
   state.pr_buffer = buf;
+  state.pr_sock   = psock;
+  
+  /* Handle any any CAN data already buffered in a read-ahead buffer.  NOTE
+   * that there may be read-ahead data to be retrieved even after the
+   * socket has been disconnected.
+   */
+  ret = can_readahead(&state);
+  if(ret > 0)
+  {
+      net_unlock();
+      nxsem_destroy(&state.pr_sem);
+      return ret;
+  }    
   
   /* Get the device driver that will service this transfer */
 
@@ -317,7 +475,7 @@ ssize_t can_recvfrom(FAR struct socket *psock, FAR void *buf,
       goto errout_with_state;
     }
     
-    /* Set up the callback in the connection */
+  /* Set up the callback in the connection */
 
   state.pr_cb = can_callback_alloc(dev, conn);
   if (state.pr_cb)
diff --git a/net/can/can_callback.c b/net/can/can_setsockopt.c
similarity index 51%
copy from net/can/can_callback.c
copy to net/can/can_setsockopt.c
index 2fad951..db4cb76 100644
--- a/net/can/can_callback.c
+++ b/net/can/can_setsockopt.c
@@ -1,7 +1,7 @@
 /****************************************************************************
- * net/pkt/pkt_callback.c
+ * net/can/can_setsockopt.c
  *
- *   Copyright (C) 2014 Gregory Nutt. All rights reserved.
+ *   Copyright (C) 2018, 2020 Gregory Nutt. All rights reserved.
  *   Author: Gregory Nutt <gn...@nuttx.org>
  *
  * Redistribution and use in source and binary forms, with or without
@@ -38,48 +38,110 @@
  ****************************************************************************/
 
 #include <nuttx/config.h>
-#if defined(CONFIG_NET) && defined(CONFIG_NET_CAN)
 
+#include <sys/time.h>
 #include <stdint.h>
+#include <errno.h>
+#include <assert.h>
 #include <debug.h>
 
-#include <nuttx/net/netconfig.h>
-#include <nuttx/net/netdev.h>
+#include <netpacket/can.h>
 
-#include "devif/devif.h"
+#include <nuttx/net/net.h>
+#include <nuttx/net/can.h>
+
+#include "socket/socket.h"
+#include "utils/utils.h"
 #include "can/can.h"
 
+#ifdef CONFIG_NET_CANPROTO_OPTIONS
+
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
 
 /****************************************************************************
- * Name: can_callback
+ * Name: can_setsockopt
  *
  * Description:
- *   Inform the application holding the packet socket of a change in state.
+ *   can_setsockopt() sets the CAN-protocol option specified by the
+ *   'option' argument to the value pointed to by the 'value' argument for
+ *   the socket specified by the 'psock' argument.
  *
- * Returned Value:
- *   OK if packet has been processed, otherwise ERROR.
+ *   See <netinet/can.h> for the a complete list of values of CAN protocol
+ *   options.
  *
- * Assumptions:
- *   This function is called with the network locked.
+ * Input Parameters:
+ *   psock     Socket structure of socket to operate on
+ *   option    identifies the option to set
+ *   value     Points to the argument value
+ *   value_len The length of the argument value
+ *
+ * Returned Value:
+ *   Returns zero (OK) on success.  On failure, it returns a negated errno
+ *   value to indicate the nature of the error.  See psock_setcockopt() for
+ *   the list of possible error values.
  *
  ****************************************************************************/
 
-uint16_t can_callback(FAR struct net_driver_s *dev,
-                      FAR struct can_conn_s *conn, uint16_t flags)
+int can_setsockopt(FAR struct socket *psock, int option,
+                   FAR const void *value, socklen_t value_len)
 {
-  /* Some sanity checking */
+    
+  FAR struct can_conn_s *conn;
+  int ret;
+  int count = 0;
+
+  DEBUGASSERT(psock != NULL && value != NULL && psock->s_conn != NULL);
+  conn = (FAR struct can_conn_s *)psock->s_conn;
 
-  if (conn)
+  if (psock->s_type != SOCK_RAW)
     {
-      /* Perform the callback */
+      nerr("ERROR:  Not a RAW CAN socket\n");
+      return -ENOTCONN;
+    }
+
+
+  switch (option)
+    {
+      case CAN_RAW_FILTER:
+        if (value_len % sizeof(struct can_filter) != 0)
+        {
+		  ret = -EINVAL;
+        }
+        
+        if (value_len > CAN_RAW_FILTER_MAX * sizeof(struct can_filter))
+        {
+		  ret = -EINVAL;
+        }
+
+		count = value_len / sizeof(struct can_filter);
+        
+        /* FIXME pass filter to driver */
+        break;
+      
+      case CAN_RAW_ERR_FILTER:
+        break;
+      
+      case CAN_RAW_LOOPBACK:
+        break;
+      
+      case CAN_RAW_RECV_OWN_MSGS:
+        break;
+      
+      case CAN_RAW_FD_FRAMES:
+        break;
+      
+      case CAN_RAW_JOIN_FILTERS:
+        break;
 
-      flags = devif_conn_event(dev, conn, flags, conn->list);
+      default:
+        nerr("ERROR: Unrecognized CAN option: %d\n", option);
+        ret = -ENOPROTOOPT;
+        break;
     }
 
-  return flags;
+  return ret;
 }
 
-#endif /* CONFIG_NET && CONFIG_NET_CAN */
+#endif /* CONFIG_NET_CANPROTO_OPTIONS */
diff --git a/net/can/can_sockif.c b/net/can/can_sockif.c
index 0cd389a..5c8415e 100644
--- a/net/can/can_sockif.c
+++ b/net/can/can_sockif.c
@@ -86,7 +86,7 @@ const struct sock_intf_s g_can_sockif =
   can_listen,       /* si_listen */
   can_connect,      /* si_connect */
   can_accept,       /* si_accept */
-  can_poll_local,         /* si_poll */
+  can_poll_local,   /* si_poll */
   can_send,         /* si_send */
   can_sendto,       /* si_sendto */
 #ifdef CONFIG_NET_SENDFILE
@@ -102,6 +102,73 @@ const struct sock_intf_s g_can_sockif =
  ****************************************************************************/
 
 /****************************************************************************
+ * Name: can_poll_eventhandler
+ *
+ * Description:
+ *   This function is called to perform the actual CAN receive operation
+ *   via the device interface layer.
+ *
+ * Input Parameters:
+ *   dev      The structure of the network driver that caused the event
+ *   conn     The connection structure associated with the socket
+ *   flags    Set of events describing why the callback was invoked
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *   This function must be called with the network locked.
+ *
+ ****************************************************************************/
+
+static uint16_t can_poll_eventhandler(FAR struct net_driver_s *dev,
+                                      FAR void *conn,
+                                      FAR void *pvpriv, uint16_t flags)
+{
+  FAR struct can_poll_s *info = (FAR struct can_poll_s *)pvpriv;
+
+  DEBUGASSERT(!info || (info->psock && info->fds));
+
+  /* 'priv' might be null in some race conditions (?) */
+
+  if (info)
+    {
+      pollevent_t eventset = 0;
+
+      /* Check for data or connection availability events. */
+
+      if ((flags & CAN_NEWDATA) != 0)
+        {
+          eventset |= (POLLIN & info->fds->events);
+        }
+
+      /* Check for loss of connection events. */
+
+      if ((flags & NETDEV_DOWN) != 0)
+        {
+          eventset |= (POLLHUP | POLLERR);
+        }
+
+      /* A poll is a sign that we are free to send data. */
+
+     /* else if ((flags & CAN_POLL) != 0 && psock_udp_cansend(info->psock) >= 0)
+        {
+          eventset |= (POLLOUT & info->fds->events);
+        }*/
+
+      /* Awaken the caller of poll() is requested event occurred. */
+
+      if (eventset)
+        {
+          info->fds->revents |= eventset;
+          nxsem_post(info->fds->sem);
+        }
+    }
+
+  return flags;
+}
+
+/****************************************************************************
  * Name: can_setup
  *
  * Description:
@@ -506,100 +573,109 @@ static int can_poll_local(FAR struct socket *psock, FAR struct pollfd *fds,
                         bool setup)
 {
   FAR struct can_conn_s *conn;
-  int ret;
+  FAR struct can_poll_s *info;
+  FAR struct devif_callback_s *cb;
+  int ret = OK;
 
   DEBUGASSERT(psock != NULL && psock->s_conn != NULL);
   conn = (FAR struct can_conn_s *)psock->s_conn;
+  info = conn->pollinfo;
+  
+  //FIXME add NETDEV_DOWN support
 
   /* Check if we are setting up or tearing down the poll */
 
   if (setup)
     {
-      /* If POLLOUT is selected, return immediately (maybe) */
-
-      pollevent_t revents = POLLOUT;
-
-      /* If POLLIN is selected and a response is available, return
-       * immediately if POLLIN and/or POLLIN are included in the
-       * requested event set.
-       */
-
+        
       net_lock();
-
-#warning Missing logic
-
-      revents &= fds->events;
-      if (revents != 0)
+      
+      info->dev = conn->dev;
+      
+      cb = can_callback_alloc(info->dev, conn);
+      if (cb == NULL)
         {
-          fds->revents = revents;
-          nxsem_post(fds->sem);
-          net_unlock();
-          return OK;
+          ret = -EBUSY;
+          goto errout_with_lock;
         }
 
-      /* Set up to be notified when a response is available if POLLIN is
-       * requested.
+      /* Initialize the poll info container */
+    
+      info->psock  = psock;
+      info->fds    = fds;
+      info->cb     = cb;
+    
+      /* Initialize the callback structure.  Save the reference to the info
+       * structure as callback private data so that it will be available during
+       * callback processing.
        */
-
+    
+      cb->flags    = NETDEV_DOWN;
+      cb->priv     = (FAR void *)info;
+      cb->event    = can_poll_eventhandler;
+    
+      if ((fds->events & POLLOUT) != 0)
+        {
+          cb->flags |= CAN_POLL;
+        }
+    
       if ((fds->events & POLLIN) != 0)
         {
-          /* Some limitations:  There can be only a single outstanding POLLIN
-           * on the CAN connection.
-           */
-
-          if (conn->pollsem != NULL || conn->pollevent != NULL)
-            {
-              nerr("ERROR: Multiple polls() on socket not supported.\n");
-              net_unlock();
-              return -EBUSY;
-            }
-
-          /* Set up the notification */
-
-          conn->pollsem    = fds->sem;
-          conn->pollevent  = &fds->revents;
-
-#warning Missing logic
-
-          if (ret < 0)
-            {
-              /* Failed to set up notification */
-
-              conn->pollsem   = NULL;
-              conn->pollevent = NULL;
-            }
-          else
-            {
-              /* Setup to receive a notification when CAN data is available */
-
-#warning Missing logic
-
-              ret = OK;
-            }
+          cb->flags |= CAN_NEWDATA;
         }
-
-      /* Set up to be notified when we are able to send CAN data without
-       * waiting.
+    
+      /* Save the reference in the poll info structure as fds private as well
+       * for use during poll teardown as well.
        */
-
-      else if ((fds->events & POLLOUT) != 0)
+    
+      fds->priv = (FAR void *)info;
+    
+      /* Check for read data availability now */
+    
+      if (!IOB_QEMPTY(&conn->readahead))
         {
+          /* Normal data may be read without blocking. */
+    
+          fds->revents |= (POLLRDNORM & fds->events);
         }
-      else
+    
+    #if 0
+      if (psock_udp_cansend(psock) >= 0)
         {
-          /* There will not be any wakeups coming?  Probably an error? */
-
-          ret = OK;
+          /* Normal data may be sent without blocking (at least one byte). */
+    
+          fds->revents |= (POLLWRNORM & fds->events);
         }
-
+    #endif
+    
+      /* Check if any requested events are already in effect */
+    
+      if (fds->revents != 0)
+        {
+          /* Yes.. then signal the poll logic */
+          nxsem_post(fds->sem);
+        }
+    
+errout_with_lock:
       net_unlock();
     }
-  else
+  else 
     {
-      /* Cancel any response notifications */
+      info = (FAR struct can_poll_s *)fds->priv;
+        
+      if (info != NULL)
+      {
+        /* Cancel any response notifications */      
+        can_callback_free(info->dev, conn, info->cb);
+
+        /* Release the poll/select data slot */
+
+        info->fds->priv = NULL;
+
+        /* Then free the poll info container */
 
-      conn->pollsem   = NULL;
-      conn->pollevent = NULL;
+        info->psock = NULL;
+      }
     }
 
   return ret;
diff --git a/net/socket/Kconfig b/net/socket/Kconfig
index c627ea5..8b71ade 100644
--- a/net/socket/Kconfig
+++ b/net/socket/Kconfig
@@ -37,6 +37,12 @@ config NET_UDPPROTO_OPTIONS
 	---help---
 		Enable or disable support for UDP protocol level socket options.
 
+config NET_CANPROTO_OPTIONS
+	bool
+	default n
+	---help---
+		Enable or disable support for CAN protocol level socket option
+
 if NET_SOCKOPTS
 
 config NET_SOLINGER
diff --git a/net/socket/getsockopt.c b/net/socket/getsockopt.c
index e7474ad..bc07a03 100644
--- a/net/socket/getsockopt.c
+++ b/net/socket/getsockopt.c
@@ -371,6 +371,12 @@ int psock_getsockopt(FAR struct socket *psock, int level, int option,
        break;
 #endif
 
+      case SOL_CAN_RAW:
+#ifdef CONFIG_NET_TCPPROTO_OPTIONS
+       ret = can_getsockopt(psock, option, value, value_len);
+#endif
+       break;
+       
       /* These levels are defined in sys/socket.h, but are not yet
        * implemented.
        */


[incubator-nuttx] 25/31: Socket: Control message addded initial stubs for sendmsg()

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch SocketCAN
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit c3cdcbfbd58bfd3c36b587ec4197d1d6ebebcdf9
Author: Peter van der Perk <pe...@nxp.com>
AuthorDate: Fri Mar 13 18:12:29 2020 +0100

    Socket: Control message addded initial stubs for sendmsg()
---
 arch/arm/src/s32k1xx/Kconfig           |   1 +
 arch/arm/src/s32k1xx/s32k1xx_flexcan.c |   9 +-
 include/netpacket/can.h                |   2 +
 include/nuttx/net/net.h                |   8 +-
 libs/libc/net/lib_recvmsg.c            |   4 +-
 libs/libc/net/lib_sendmsg.c            |   4 +-
 net/bluetooth/bluetooth_sockif.c       |   3 +-
 net/can/Kconfig                        |  20 ++++
 net/can/can.h                          |  16 +--
 net/can/can_getsockopt.c               |  21 ++++
 net/can/can_recvfrom.c                 | 191 +++++++++++++++------------------
 net/can/can_send.c                     |   4 +
 net/can/can_setsockopt.c               |  10 ++
 net/can/can_sockif.c                   |  51 ++++++++-
 net/icmp/icmp_sockif.c                 |   3 +-
 net/icmpv6/icmpv6_sockif.c             |   3 +-
 net/ieee802154/ieee802154_sockif.c     |   3 +-
 net/inet/inet_sockif.c                 |   3 +-
 net/local/local_sockif.c               |   3 +-
 net/netlink/netlink_sockif.c           |   3 +-
 net/pkt/pkt_sockif.c                   |   3 +-
 net/socket/Kconfig                     |  14 +--
 net/socket/Make.defs                   |   5 +-
 net/socket/recvmsg.c                   |   4 +-
 net/socket/{recvmsg.c => sendmsg.c}    |  68 ++++++------
 25 files changed, 280 insertions(+), 176 deletions(-)

diff --git a/arch/arm/src/s32k1xx/Kconfig b/arch/arm/src/s32k1xx/Kconfig
index 68f9bb6..41638d0 100644
--- a/arch/arm/src/s32k1xx/Kconfig
+++ b/arch/arm/src/s32k1xx/Kconfig
@@ -152,6 +152,7 @@ config S32K1XX_ENET
 
 config S32K1XX_FLEXCAN
 	bool "FLEXCAN"
+	select NET_CAN_HAVE_TX_DEADLINE
 	default n
 
 menuconfig S32K1XX_LPI2C0
diff --git a/arch/arm/src/s32k1xx/s32k1xx_flexcan.c b/arch/arm/src/s32k1xx/s32k1xx_flexcan.c
index 15e5b62..5c02aa0 100644
--- a/arch/arm/src/s32k1xx/s32k1xx_flexcan.c
+++ b/arch/arm/src/s32k1xx/s32k1xx_flexcan.c
@@ -433,10 +433,7 @@ static int s32k1xx_transmit(FAR struct s32k1xx_driver_s *priv)
           mb->id.std = frame->can_id & MASKSTDID;
         }
 
-  #if 0
-      /* cs.rtr = frame.isRemoteTransmissionRequest(); */
-  #endif
-
+      cs.rtr = frame->can_id & FLAGRTR ? 1 : 0;
       cs.dlc = frame->can_dlc;
 
       mb->data[0].w00 = __builtin_bswap32(*(uint32_t *)&frame->data[0]);
@@ -458,9 +455,7 @@ static int s32k1xx_transmit(FAR struct s32k1xx_driver_s *priv)
           mb->id.std = frame->can_id & MASKSTDID;
         }
 
-#if 0
-      /* cs.rtr = frame.isRemoteTransmissionRequest(); */
-#endif
+      cs.rtr = frame->can_id & FLAGRTR ? 1 : 0;
 
       if (frame->len < 9)
         {
diff --git a/include/netpacket/can.h b/include/netpacket/can.h
index 4ea2104..bd0442d 100644
--- a/include/netpacket/can.h
+++ b/include/netpacket/can.h
@@ -75,6 +75,8 @@
                                  /* allow CAN FD frames (default:off) */
 #define CAN_RAW_JOIN_FILTERS   (__SO_PROTOCOL + 5)     
                                  /* all filters must match to trigger */
+#define CAN_RAW_TX_DEADLINE    (__SO_PROTOCOL + 6)
+                                 /* Abort frame when deadline has been passed */
 
 /****************************************************************************
  * Public Types
diff --git a/include/nuttx/net/net.h b/include/nuttx/net/net.h
index 27c5fe9..055c865 100644
--- a/include/nuttx/net/net.h
+++ b/include/nuttx/net/net.h
@@ -217,7 +217,7 @@ struct sock_intf_s
                     FAR socklen_t *fromlen);
 #ifdef CONFIG_NET_RECVMSG_CMSG
   CODE ssize_t    (*si_recvmsg)(FAR struct socket *psock,
-                FAR struct msghdr *msg, int flags);
+		            FAR struct msghdr *msg, int flags);
 #endif
   CODE int        (*si_close)(FAR struct socket *psock);
 #ifdef CONFIG_NET_USRSOCK
@@ -507,9 +507,9 @@ FAR struct iob_s *net_ioballoc(bool throttled, enum iob_user_e consumerid);
  * Description:
  *   Check if the socket descriptor is valid for the provided TCB and if it
  *   supports the requested access.  This trivial operation is part of the
- *   fdopen() operation when the fdopen() is performed on a socket
- *   descriptor.  It simply performs some sanity checking before permitting
- *   the socket descriptor to be wrapped as a C FILE stream.
+ *   fdopen() operation when the fdopen() is performed on a socket descriptor.
+ *   It simply performs some sanity checking before permitting the socket
+ *   descriptor to be wrapped as a C FILE stream.
  *
  ****************************************************************************/
 
diff --git a/libs/libc/net/lib_recvmsg.c b/libs/libc/net/lib_recvmsg.c
index 5200acd..071c189 100644
--- a/libs/libc/net/lib_recvmsg.c
+++ b/libs/libc/net/lib_recvmsg.c
@@ -39,7 +39,7 @@
 
 #include <nuttx/config.h>
 
-#if defined(CONFIG_NET) && !defined(CONFIG_NET_RECVMSG_CMSG)
+#if defined(CONFIG_NET) && !defined(CONFIG_NET_CMSG)
 
 #include <sys/types.h>
 #include <sys/socket.h>
@@ -87,4 +87,4 @@ ssize_t recvmsg(int sockfd, FAR struct msghdr *msg, int flags)
     }
 }
 
-#endif /* CONFIG_NET && !CONFIG_NET_RECVMSG_CMSG */
+#endif /* CONFIG_NET && !CONFIG_NET_CMSG */
diff --git a/libs/libc/net/lib_sendmsg.c b/libs/libc/net/lib_sendmsg.c
index 0d09faa..9f98e51 100644
--- a/libs/libc/net/lib_sendmsg.c
+++ b/libs/libc/net/lib_sendmsg.c
@@ -39,7 +39,7 @@
 
 #include <nuttx/config.h>
 
-#ifdef CONFIG_NET
+#if defined(CONFIG_NET) && !defined(CONFIG_NET_CMSG)
 
 #include <sys/types.h>
 #include <sys/socket.h>
@@ -86,4 +86,4 @@ ssize_t sendmsg(int sockfd, FAR struct msghdr *msg, int flags)
     }
 }
 
-#endif /* CONFIG_NET */
+#endif /* CONFIG_NET && !CONFIG_NET_CMSG */
diff --git a/net/bluetooth/bluetooth_sockif.c b/net/bluetooth/bluetooth_sockif.c
index fd6d95f..4057d93 100644
--- a/net/bluetooth/bluetooth_sockif.c
+++ b/net/bluetooth/bluetooth_sockif.c
@@ -109,8 +109,9 @@ const struct sock_intf_s g_bluetooth_sockif =
   NULL,                  /* si_sendfile */
 #endif
   bluetooth_recvfrom,    /* si_recvfrom */
-#ifdef CONFIG_NET_RECVMSG_CMSG
+#ifdef CONFIG_NET_CMSG
   NULL,                  /* si_recvmsg */
+  NULL,                  /* si_sendmsg */
 #endif
   bluetooth_close        /* si_close */
 };
diff --git a/net/can/Kconfig b/net/can/Kconfig
index 3b2e450..ac94021 100644
--- a/net/can/Kconfig
+++ b/net/can/Kconfig
@@ -18,6 +18,10 @@ config NET_CAN
 
 if NET_CAN
 
+config NET_CAN_HAVE_TX_DEADLINE
+	bool
+	default n
+
 config CAN_CONNS
 	int "Number of CAN connections"
 	default 4
@@ -27,9 +31,25 @@ config CAN_CONNS
 config NET_CAN_SOCK_OPTS
 	bool "sockopt support"
 	default n
+	select NET_SOCKOPTS
 	select NET_CANPROTO_OPTIONS
 	---help---
 		Enable support for the CAN socket options
+				
+config NET_CAN_RAW_TX_DEADLINE
+	bool "TX deadline sockopt"
+	default n
+	depends on NET_CAN_SOCK_OPTS && NET_CAN_HAVE_TX_DEADLINE
+	select NET_CMSG
+	---help---
+	    Note: Non-standard SocketCAN sockopt, but this options helps us in
+	    real-time use cases.
+	    
+		When the CAN_RAW_TX_DEADLINE sockopt is enabled. The user can send 
+		CAN frames using sendmsg() function and add a deadline timespec 
+		value in the CMSG data. When the deadline has been passed and the
+		CAN frame is still in the HW TX mailbox then the CAN driver will 
+		discard the CAN frame automatically.
 		
 config NET_CAN_RAW_FILTER_MAX
 	int "CAN_RAW_FILTER max filter count"
diff --git a/net/can/can.h b/net/can/can.h
index 7c6b614..00c297d 100644
--- a/net/can/can.h
+++ b/net/can/can.h
@@ -104,20 +104,23 @@ struct can_conn_s
    */
 
   struct can_poll_s pollinfo[4]; /* FIXME make dynamic */
-
+  
 #ifdef CONFIG_NET_CANPROTO_OPTIONS
   int32_t loopback;
   int32_t recv_own_msgs;
   int32_t fd_frames;
   struct can_filter filters[CONFIG_NET_CAN_RAW_FILTER_MAX];
   int32_t filter_count;
-
-  /* TODO add filter support */
+# ifdef CONFIG_NET_CAN_RAW_TX_DEADLINE
+  int32_t tx_deadline;
+# endif
 #endif
-
+  
 #ifdef CONFIG_NET_TIMESTAMP
   FAR struct socket *psock; /* Needed to get SO_TIMESTAMP value */
 #endif
+
+  
 };
 
 /****************************************************************************
@@ -166,8 +169,8 @@ FAR struct can_conn_s *can_alloc(void);
  * Name: can_free()
  *
  * Description:
- *   Free a NetLink connection structure that is no longer in use. This
- *   should be done by the implementation of close().
+ *   Free a NetLink connection structure that is no longer in use. This should
+ *   be done by the implementation of close().
  *
  ****************************************************************************/
 
@@ -256,6 +259,7 @@ uint16_t can_datahandler(FAR struct can_conn_s *conn, FAR uint8_t *buffer,
  *
  ****************************************************************************/
 
+
 ssize_t can_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
                      int flags, FAR struct sockaddr *from,
                      FAR socklen_t *fromlen);
diff --git a/net/can/can_getsockopt.c b/net/can/can_getsockopt.c
index 238695c..17184e2 100644
--- a/net/can/can_getsockopt.c
+++ b/net/can/can_getsockopt.c
@@ -188,6 +188,27 @@ int can_getsockopt(FAR struct socket *psock, int option,
       case CAN_RAW_JOIN_FILTERS:
         break;
 
+#ifdef CONFIG_NET_CAN_RAW_TX_DEADLINE
+      case CAN_RAW_TX_DEADLINE:
+        if (*value_len < sizeof(conn->tx_deadline))
+          {
+            /* REVISIT: POSIX says that we should truncate the value if it
+             * is larger than value_len.   That just doesn't make sense
+             * to me in this case.
+             */
+
+            ret              = -EINVAL;
+          }
+        else
+          {
+            FAR int *tx_deadline = (FAR int32_t *)value;
+            *tx_deadline         = conn->tx_deadline;
+            *value_len         = sizeof(conn->tx_deadline);
+            ret                = OK;
+          }
+        break;
+#endif
+
       default:
         nerr("ERROR: Unrecognized RAW CAN socket option: %d\n", option);
         ret = -ENOPROTOOPT;
diff --git a/net/can/can_recvfrom.c b/net/can/can_recvfrom.c
index 2211ed0..d9ed8cb 100644
--- a/net/can/can_recvfrom.c
+++ b/net/can/can_recvfrom.c
@@ -50,19 +50,20 @@
 #include <sys/time.h>
 #endif
 
+
 /****************************************************************************
  * Private Types
  ****************************************************************************/
 
 struct can_recvfrom_s
 {
-  FAR struct socket *pr_sock;          /* The parent socket structure */
+  FAR struct socket       *pr_sock;      /* The parent socket structure */
   FAR struct devif_callback_s *pr_cb;  /* Reference to callback instance */
   sem_t        pr_sem;                 /* Semaphore signals recv completion */
   size_t       pr_buflen;              /* Length of receive buffer */
   FAR uint8_t *pr_buffer;              /* Pointer to receive buffer */
   ssize_t      pr_recvlen;             /* The received length */
-#ifdef CONFIG_NET_RECVMSG_CMSG
+#ifdef CONFIG_NET_CMSG
   size_t       pr_msglen;              /* Length of msg buffer */
   FAR uint8_t *pr_msgbuf;              /* Pointer to msg buffer */
 #endif
@@ -232,15 +233,14 @@ static inline void can_newdata(FAR struct net_driver_s *dev,
 
 static inline int can_readahead(struct can_recvfrom_s *pstate)
 {
-  FAR struct can_conn_s *conn =
-    (FAR struct can_conn_s *) pstate->pr_sock->s_conn;
+  FAR struct can_conn_s *conn = (FAR struct can_conn_s *)pstate->pr_sock->s_conn;
   FAR struct iob_s *iob;
   int recvlen;
 
   /* Check there is any CAN data already buffered in a read-ahead
    * buffer.
    */
-
+  
   pstate->pr_recvlen = -1;
 
   if ((iob = iob_peek_queue(&conn->readahead)) != NULL &&
@@ -287,16 +287,15 @@ static inline int can_readahead(struct can_recvfrom_s *pstate)
                              IOBUSER_NET_CAN_READAHEAD);
         }
 
-      /* do not pass frames with DLC > 8 to a legacy socket */
-
-      if (!conn->fd_frames)
-        {
-          struct canfd_frame *cfd = (struct canfd_frame *)pstate->pr_buffer;
-          if (cfd->len > CAN_MAX_DLEN)
-            {
-              return 0;
-            }
-        }
+	  /* do not pass frames with DLC > 8 to a legacy socket */
+	  if (!conn->fd_frames)
+	    {
+		  struct canfd_frame *cfd = (struct canfd_frame *)pstate->pr_buffer;
+		  if (cfd->len > CAN_MAX_DLEN)
+		    {
+	  			return 0;
+		    }
+	    }
 
       return recvlen;
     }
@@ -320,14 +319,13 @@ static inline int can_readahead(struct can_recvfrom_s *pstate)
  *   The network is locked.
  *
  ****************************************************************************/
-
 #ifdef CONFIG_NET_TIMESTAMP
-static inline int can_readahead_timestamp(struct can_conn_s *conn,
-                                          FAR uint8_t *buffer)
+static inline int can_readahead_timestamp(struct can_conn_s *conn, FAR uint8_t *buffer)
 {
   FAR struct iob_s *iob;
   int recvlen;
 
+
   if ((iob = iob_peek_queue(&conn->readahead)) != NULL)
     {
       DEBUGASSERT(iob->io_pktlen > 0);
@@ -381,27 +379,26 @@ static inline int can_readahead_timestamp(struct can_conn_s *conn,
 #ifdef CONFIG_NET_CANPROTO_OPTIONS
 static int can_recv_filter(struct can_conn_s *conn, canid_t id)
 {
-  for (int i = 0; i < conn->filter_count; i++)
+  for(int i = 0; i < conn->filter_count; i++)
     {
-      if (conn->filters[i].can_id & CAN_INV_FILTER)
-        {
-          if ((id & conn->filters[i].can_mask) !=
-                ((conn->filters[i].can_id & ~CAN_INV_FILTER) &
-                conn->filters[i].can_mask))
-            {
-              return 1;
-            }
-        }
-      else
-        {
-          if ((id & conn->filters[i].can_mask) ==
-                (conn->filters[i].can_id & conn->filters[i].can_mask))
-            {
-              return 1;
-            }
-        }
+	  if (conn->filters[i].can_id & CAN_INV_FILTER)
+	    {
+		  if((id & conn->filters[i].can_mask) !=
+				  ((conn->filters[i].can_id & ~CAN_INV_FILTER)
+						  & conn->filters[i].can_mask))
+		    {
+			  return 1;
+		    }
+	    }
+	  else
+	    {
+		  if((id & conn->filters[i].can_mask) ==
+				  (conn->filters[i].can_id & conn->filters[i].can_mask))
+		    {
+			  return 1;
+		    }
+	    }
     }
-
   return 0;
 }
 #endif
@@ -419,50 +416,46 @@ static uint16_t can_recvfrom_eventhandler(FAR struct net_driver_s *dev,
     {
       if ((flags & CAN_NEWDATA) != 0)
         {
-          /* If a new packet is available, check receive filters
-           * when is valid then complete the read action.
-           */
+    	  /* If a new packet is available, check receive filters
+    	   * when is valid then complete the read action. */
 #ifdef CONFIG_NET_CANPROTO_OPTIONS
-          if (can_recv_filter(conn, (canid_t) *dev->d_appdata) == 0)
-            {
-              flags &= ~CAN_NEWDATA;
-              return flags;
-            }
+    	  if(can_recv_filter(conn,(canid_t)*dev->d_appdata) == 0)
+    	    {
+    		  flags &= ~CAN_NEWDATA;
+    	  	  return flags;
+    		}
 #endif
 
-          /* do not pass frames with DLC > 8 to a legacy socket */
-
-          if (!conn->fd_frames)
-            {
-              struct canfd_frame *cfd = (struct canfd_frame *)dev->d_appdata;
-              if (cfd->len > CAN_MAX_DLEN)
-                {
-                  /* DO WE NEED TO CLEAR FLAGS?? */
-
-                  flags &= ~CAN_NEWDATA;
-                  return flags;
-                }
-            }
+    	  /* do not pass frames with DLC > 8 to a legacy socket */
+    	  if (!conn->fd_frames)
+    	    {
+    		  struct canfd_frame *cfd = (struct canfd_frame*)dev->d_appdata;
+    	      if (cfd->len > CAN_MAX_DLEN)
+    	      {
+    	    	/* DO WE NEED TO CLEAR FLAGS?? */
+    	        flags &= ~CAN_NEWDATA;
+  	  			return flags;
+    	      }
+    	    }
 
           /* Copy the packet */
 
           can_newdata(dev, pstate);
 
 #ifdef CONFIG_NET_TIMESTAMP
-          if (pstate->pr_sock->s_timestamp)
-            {
-              if (pstate->pr_msglen == sizeof(struct timeval))
-                {
-                  can_readahead_timestamp(conn, pstate->pr_msgbuf);
-                }
-              else
-                {
-                  /* We still have to consume the data otherwise IOB gets full */
-
-                  uint8_t dummy_buf[sizeof(struct timeval)];
-                  can_readahead_timestamp(conn, &dummy_buf);
-                }
-            }
+		  if(pstate->pr_sock->s_timestamp)
+			{
+			  if(pstate->pr_msglen == sizeof(struct timeval))
+			    {
+				  can_readahead_timestamp(conn, pstate->pr_msgbuf);
+			    }
+			  else
+			    {
+				/* We still have to consume the data otherwise IOB gets full */
+				  uint8_t dummy_buf[sizeof(struct timeval)];
+				  can_readahead_timestamp(conn, &dummy_buf);
+			    }
+			}
 #endif
 
           /* We are finished. */
@@ -515,7 +508,6 @@ static ssize_t can_recvfrom_result(int result,
   if (pstate->pr_result < 0)
     {
       /* This might return EAGAIN on a timeout */
-
       return pstate->pr_result;
     }
 
@@ -600,10 +592,10 @@ ssize_t can_recvfrom(FAR struct socket *psock, FAR void *buf,
 
   ret = can_readahead(&state);
   if (ret > 0)
-    {
+    {      
       goto errout_with_state;
     }
-
+    
   ret = state.pr_recvlen;
 
   /* Handle non-blocking CAN sockets */
@@ -618,7 +610,7 @@ ssize_t can_recvfrom(FAR struct socket *psock, FAR void *buf,
         {
           /* Nothing was received */
 
-          ret = -EAGAIN;
+          ret = -EAGAIN;          
           goto errout_with_state;
         }
     }
@@ -683,7 +675,6 @@ errout_with_state:
  *   flags    Receive flags (ignored)
  *
  ****************************************************************************/
-
 #ifdef CONFIG_NET_RECVMSG_CMSG
 ssize_t can_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg,
                     size_t len, int flags)
@@ -716,22 +707,20 @@ ssize_t can_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg,
   nxsem_init(&state.pr_sem, 0, 0); /* Doesn't really fail */
   nxsem_setprotocol(&state.pr_sem, SEM_PRIO_NONE);
 
+
   state.pr_buflen = msg->msg_iov->iov_len;
   state.pr_buffer = msg->msg_iov->iov_base;
-
 #ifdef CONFIG_NET_TIMESTAMP
-  if (psock->s_timestamp && msg->msg_controllen ==
-        (sizeof(struct cmsghdr) + sizeof(struct timeval)))
+  if(psock->s_timestamp && msg->msg_controllen == (sizeof(struct cmsghdr) + sizeof(struct timeval)))
     {
-      struct cmsghdr *cmsg = CMSG_FIRSTHDR(msg);
-      state.pr_msglen = sizeof(struct timeval);
-      state.pr_msgbuf = CMSG_DATA(cmsg);
-      cmsg->cmsg_level = SOL_SOCKET;
-      cmsg->cmsg_type = SO_TIMESTAMP;
-      cmsg->cmsg_len = state.pr_msglen;
+	  struct cmsghdr* cmsg = CMSG_FIRSTHDR(msg);
+	  state.pr_msglen = sizeof(struct timeval);
+	  state.pr_msgbuf = CMSG_DATA(cmsg);
+	  cmsg->cmsg_level = SOL_SOCKET;
+	  cmsg->cmsg_type = SO_TIMESTAMP;
+	  cmsg->cmsg_len = state.pr_msglen;
     }
 #endif
-
   state.pr_sock   = psock;
 
   /* Handle any any CAN data already buffered in a read-ahead buffer.  NOTE
@@ -743,22 +732,20 @@ ssize_t can_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg,
   if (ret > 0)
     {
 #ifdef CONFIG_NET_TIMESTAMP
-      if (psock->s_timestamp)
-        {
-          if (state.pr_msglen == sizeof(struct timeval))
-            {
-              can_readahead_timestamp(conn, state.pr_msgbuf);
-            }
-          else
-            {
-              /* We still have to consume the data otherwise IOB gets full */
-
-              uint8_t dummy_buf[sizeof(struct timeval)];
-              can_readahead_timestamp(conn, &dummy_buf);
-            }
-        }
+	  if(psock->s_timestamp)
+	    {
+		  if(state.pr_msglen == sizeof(struct timeval))
+		    {
+			  can_readahead_timestamp(conn, state.pr_msgbuf);
+		    }
+		  else
+		    {
+			/* We still have to consume the data otherwise IOB gets full */
+		    uint8_t dummy_buf[sizeof(struct timeval)];
+			can_readahead_timestamp(conn, &dummy_buf);
+		    }
+	    }
 #endif
-
       goto errout_with_state;
     }
 
diff --git a/net/can/can_send.c b/net/can/can_send.c
index 644adc3..dfb03d0 100644
--- a/net/can/can_send.c
+++ b/net/can/can_send.c
@@ -76,6 +76,10 @@ struct send_s
   sem_t                   snd_sem;     /* Used to wake up the waiting thread */
   FAR const uint8_t      *snd_buffer;  /* Points to the buffer of data to send */
   size_t                  snd_buflen;  /* Number of bytes in the buffer to send */
+#ifdef CONFIG_NET_CMSG
+  size_t                  pr_msglen;   /* Length of msg buffer */
+  FAR uint8_t            *pr_msgbuf;   /* Pointer to msg buffer */
+#endif
   ssize_t                 snd_sent;    /* The number of bytes sent */
 };
 
diff --git a/net/can/can_setsockopt.c b/net/can/can_setsockopt.c
index 6858c1a..ac9f912 100644
--- a/net/can/can_setsockopt.c
+++ b/net/can/can_setsockopt.c
@@ -147,6 +147,16 @@ int can_setsockopt(FAR struct socket *psock, int option,
       case CAN_RAW_JOIN_FILTERS:
         break;
 
+#ifdef CONFIG_NET_CAN_RAW_TX_DEADLINE
+      case CAN_RAW_TX_DEADLINE:
+  		if (value_len != sizeof(conn->tx_deadline))
+  			return -EINVAL;
+
+  		conn->tx_deadline = *(FAR int32_t *)value;
+
+  		break;
+#endif
+
       default:
         nerr("ERROR: Unrecognized CAN option: %d\n", option);
         ret = -ENOPROTOOPT;
diff --git a/net/can/can_sockif.c b/net/can/can_sockif.c
index 737788e..09a61d0 100644
--- a/net/can/can_sockif.c
+++ b/net/can/can_sockif.c
@@ -69,6 +69,10 @@ static ssize_t can_send(FAR struct socket *psock,
 static ssize_t can_sendto(FAR struct socket *psock, FAR const void *buf,
               size_t len, int flags, FAR const struct sockaddr *to,
               socklen_t tolen);
+#ifdef CONFIG_NET_CMSG
+static ssize_t can_sendmsg(FAR struct socket *psock, FAR struct msghdr *msg,
+                    size_t len, int flags);
+#endif
 static int can_close(FAR struct socket *psock);
 
 /****************************************************************************
@@ -93,8 +97,9 @@ const struct sock_intf_s g_can_sockif =
   NULL,             /* si_sendfile */
 #endif
   can_recvfrom,     /* si_recvfrom */
-#ifdef CONFIG_NET_RECVMSG_CMSG
+#ifdef CONFIG_NET_CMSG
   can_recvmsg,      /* si_recvmsg */
+  can_sendmsg,      /* si_sendmsg */
 #endif
   can_close         /* si_close */
 };
@@ -774,6 +779,50 @@ static ssize_t can_sendto(FAR struct socket *psock, FAR const void *buf,
 }
 
 /****************************************************************************
+ * Name: can_sendmsg
+ *
+ * Description:
+ *   The can_sendmsg() send a CAN frame to psock
+ *
+ * Input Parameters:
+ *   psock - An instance of the internal socket structure.
+ *   msg   - CAN frame and optional CMSG
+ *   flags - Send flags (ignored)
+ *
+ * Returned Value:
+ *   On success, returns the number of characters sent.  On  error, a negated
+ *   errno value is returned (see send() for the list of appropriate error
+ *   values.
+ *
+ ****************************************************************************/
+#ifdef CONFIG_NET_CMSG
+static ssize_t can_sendmsg(FAR struct socket *psock, FAR struct msghdr *msg,
+                    size_t len, int flags);
+{
+  ssize_t ret;
+
+  /* Only SOCK_RAW is supported */
+
+  if (psock->s_type == SOCK_RAW)
+    {
+      /* Raw packet send */
+
+      ret = psock_can_send(psock, buf, len);
+    }
+  else
+    {
+      /* EDESTADDRREQ.  Signifies that the socket is not connection-mode and
+       * no peer address is set.
+       */
+
+      ret = -EDESTADDRREQ;
+    }
+
+  return ret;
+}
+#endif
+
+/****************************************************************************
  * Name: can_close
  *
  * Description:
diff --git a/net/icmp/icmp_sockif.c b/net/icmp/icmp_sockif.c
index c81592e..ebe2bab 100644
--- a/net/icmp/icmp_sockif.c
+++ b/net/icmp/icmp_sockif.c
@@ -102,8 +102,9 @@ const struct sock_intf_s g_icmp_sockif =
   NULL,             /* si_sendfile */
 #endif
   icmp_recvfrom,    /* si_recvfrom */
-#ifdef CONFIG_NET_RECVMSG_CMSG
+#ifdef CONFIG_NET_CMSG
   NULL,             /* si_recvmsg */
+  NULL,             /* si_sendmsg */
 #endif
   icmp_close        /* si_close */
 };
diff --git a/net/icmpv6/icmpv6_sockif.c b/net/icmpv6/icmpv6_sockif.c
index 29e5e47..5adae60 100644
--- a/net/icmpv6/icmpv6_sockif.c
+++ b/net/icmpv6/icmpv6_sockif.c
@@ -102,8 +102,9 @@ const struct sock_intf_s g_icmpv6_sockif =
   NULL,               /* si_sendfile */
 #endif
   icmpv6_recvfrom,    /* si_recvfrom */
-#ifdef CONFIG_NET_RECVMSG_CMSG
+#ifdef CONFIG_NET_CMSG
   NULL,               /* si_recvmsg */
+  NULL,               /* si_sendmsg */
 #endif
   icmpv6_close        /* si_close */
 };
diff --git a/net/ieee802154/ieee802154_sockif.c b/net/ieee802154/ieee802154_sockif.c
index d1ac29b..6c0f88a 100644
--- a/net/ieee802154/ieee802154_sockif.c
+++ b/net/ieee802154/ieee802154_sockif.c
@@ -107,8 +107,9 @@ const struct sock_intf_s g_ieee802154_sockif =
   NULL,                   /* si_sendfile */
 #endif
   ieee802154_recvfrom,    /* si_recvfrom */
-#ifdef CONFIG_NET_RECVMSG_CMSG
+#ifdef CONFIG_NET_CMSG
   NULL,                   /* si_recvmsg */
+  NULL,                   /* si_sendmsg */
 #endif
   ieee802154_close        /* si_close */
 };
diff --git a/net/inet/inet_sockif.c b/net/inet/inet_sockif.c
index 2a09c45..488f2d1 100644
--- a/net/inet/inet_sockif.c
+++ b/net/inet/inet_sockif.c
@@ -117,8 +117,9 @@ static const struct sock_intf_s g_inet_sockif =
   inet_sendfile,    /* si_sendfile */
 #endif
   inet_recvfrom,    /* si_recvfrom */
-#ifdef CONFIG_NET_RECVMSG_CMSG
+#ifdef CONFIG_NET_CMSG
   NULL,             /* si_recvmsg */
+  NULL,             /* si_sendmsg */
 #endif
   inet_close        /* si_close */
 };
diff --git a/net/local/local_sockif.c b/net/local/local_sockif.c
index 62d56b5..cd9bd66 100644
--- a/net/local/local_sockif.c
+++ b/net/local/local_sockif.c
@@ -110,8 +110,9 @@ const struct sock_intf_s g_local_sockif =
   NULL,              /* si_sendfile */
 #endif
   local_recvfrom,    /* si_recvfrom */
-#ifdef CONFIG_NET_RECVMSG_CMSG
+#ifdef CONFIG_NET_CMSG
   NULL,              /* si_recvmsg */
+  NULL,              /* si_sendmsg */
 #endif
   local_close        /* si_close */
 };
diff --git a/net/netlink/netlink_sockif.c b/net/netlink/netlink_sockif.c
index 970aed4..34b011a 100644
--- a/net/netlink/netlink_sockif.c
+++ b/net/netlink/netlink_sockif.c
@@ -111,8 +111,9 @@ const struct sock_intf_s g_netlink_sockif =
   NULL,                 /* si_sendfile */
 #endif
   netlink_recvfrom,     /* si_recvfrom */
-#ifdef CONFIG_NET_RECVMSG_CMSG
+#ifdef CONFIG_NET_CMSG
   NULL,                 /* si_recvmsg */
+  NULL,                 /* si_sendmsg */
 #endif
   netlink_close         /* si_close */
 };
diff --git a/net/pkt/pkt_sockif.c b/net/pkt/pkt_sockif.c
index bbabf42..dbf3e3c 100644
--- a/net/pkt/pkt_sockif.c
+++ b/net/pkt/pkt_sockif.c
@@ -108,8 +108,9 @@ const struct sock_intf_s g_pkt_sockif =
   NULL,            /* si_sendfile */
 #endif
   pkt_recvfrom,    /* si_recvfrom */
-#ifdef CONFIG_NET_RECVMSG_CMSG
+#ifdef CONFIG_NET_CMSG
   NULL,            /* si_recvmsg */
+  NULL,            /* si_sendmsg */
 #endif
   pkt_close        /* si_close */
 };
diff --git a/net/socket/Kconfig b/net/socket/Kconfig
index f4c9408..f13e22d 100644
--- a/net/socket/Kconfig
+++ b/net/socket/Kconfig
@@ -58,18 +58,20 @@ config NET_SOLINGER
 config NET_TIMESTAMP
 	bool "SO_TIMESTAMP socket option"
 	default n
-	depends on NET_CAN && NET_RECVMSG_CMSG
+	depends on NET_CAN
+	select NET_CMSG
 	---help---
 		Enable or disable support for the SO_TIMESTAMP socket option. Currently only tested & implemented in SocketCAN but should work on all sockets
 
 endif # NET_SOCKOPTS
 
-config NET_RECVMSG_CMSG
-	bool "recvmsg() control messages (CMSG) support"
+config NET_CMSG
+	bool "Control messages (CMSG) support"
 	default n
 	---help---
-		Enable or disable support for control messages in the recvmsg function.
-		Control messages (also defined in POSIX 1003.1g as ancillary data object information).
-		Includes additional information on the packet received.
+		Enable or disable support for control messages in the recvmsg() and
+		sendmsg() function. Control messages (also defined in POSIX 1003.1g 
+		as ancillary data object information). Includes additional 
+		information on the packet received or to be transmitted.
 
 endmenu # Socket Support
diff --git a/net/socket/Make.defs b/net/socket/Make.defs
index 2be9dbf..6bf79ed 100644
--- a/net/socket/Make.defs
+++ b/net/socket/Make.defs
@@ -75,7 +75,8 @@ endif
 DEPPATH += --dep-path socket
 VPATH += :socket
 
-# Support for recvmsg() with control messages (CMSG)
-ifeq ($(CONFIG_NET_RECVMSG_CMSG),y)
+# Support for control messages (CMSG)
+ifeq ($(CONFIG_NET_CMSG),y)
 SOCK_CSRCS += recvmsg.c
+SOCK_CSRCS += sendmsg.c
 endif
diff --git a/net/socket/recvmsg.c b/net/socket/recvmsg.c
index 17d4dfe..800eeb1 100644
--- a/net/socket/recvmsg.c
+++ b/net/socket/recvmsg.c
@@ -47,7 +47,7 @@
 
 #include "socket/socket.h"
 
-#ifdef CONFIG_NET_RECVMSG_CMSG
+#ifdef CONFIG_NET_CMSG
 
 /****************************************************************************
  * Public Functions
@@ -235,4 +235,4 @@ ssize_t recvmsg(int sockfd, FAR struct msghdr *msg, int flags)
   return ret;
 }
 
-#endif /* CONFIG_NET_RECVMSG_CMSG */
+#endif /* CONFIG_NET_CMSG */
diff --git a/net/socket/recvmsg.c b/net/socket/sendmsg.c
similarity index 78%
copy from net/socket/recvmsg.c
copy to net/socket/sendmsg.c
index 17d4dfe..3bc32e8 100644
--- a/net/socket/recvmsg.c
+++ b/net/socket/sendmsg.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * net/socket/recvmsg.c
+ * net/socket/sendmsg.c
  *
  *   Copyright (C) 2007-2009, 2011-2017, 2019 Gregory Nutt. All rights reserved.
  *   Author: Gregory Nutt <gn...@nuttx.org>
@@ -47,20 +47,20 @@
 
 #include "socket/socket.h"
 
-#ifdef CONFIG_NET_RECVMSG_CMSG
+#ifdef CONFIG_NET_CMSG
 
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
 
 /****************************************************************************
- * Name: psock_recvmsg
+ * Name: psock_sendmsg
  *
  * Description:
- *   psock_recvfrom() receives messages from a socket, and may be used to
- *   receive data on a socket whether or not it is connection-oriented.
+ *   psock_sendfrom() sends messages to a socket, and may be used to
+ *   send data on a socket whether or not it is connection-oriented.
  *   This is an internal OS interface.  It is functionally equivalent to
- *   recvfrom() except that:
+ *   sendfrom() except that:
  *
  *   - It is not a cancellation point,
  *   - It does not modify the errno variable, and
@@ -69,20 +69,20 @@
  *
  * Input Parameters:
  *   psock   - A pointer to a NuttX-specific, internal socket structure
- *   msg      Buffer to receive msg
+ *   msg     - Buffer to of the msg
  *   len     - Length of buffer
  *   flags   - Receive flags
  *
  * Returned Value:
  *   On success, returns the number of characters sent.  If no data is
  *   available to be received and the peer has performed an orderly shutdown,
- *   recv() will return 0.  Otherwise, on any failure, a negated errno value
+ *   send() will return 0.  Otherwise, on any failure, a negated errno value
  *   is returned (see comments with send() for a list of appropriate errno
  *   values).
  *
  ****************************************************************************/
 
-ssize_t psock_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg,
+ssize_t psock_sendmsg(FAR struct socket *psock, FAR struct msghdr *msg,
                        int flags)
 {
   /* Verify that non-NULL pointers were passed */
@@ -103,38 +103,38 @@ ssize_t psock_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg,
       return -EBADF;
     }
 
-  /* Let logic specific to this address family handle the recvfrom()
+  /* Let logic specific to this address family handle the sendfrom()
    * operation.
    */
 
   DEBUGASSERT(psock->s_sockif != NULL &&
-              (psock->s_sockif->si_recvmsg != NULL ||
-               psock->s_sockif->si_recvfrom != NULL));
+              (psock->s_sockif->si_sendmsg != NULL ||
+               psock->s_sockif->si_sendto != NULL));
 
-  if(psock->s_sockif->si_recvmsg != NULL)
+  if(psock->s_sockif->si_sendmsg != NULL)
     {
-	  return psock->s_sockif->si_recvmsg(psock, msg, flags);
+	  return psock->s_sockif->si_sendmsg(psock, msg, flags);
     }
   else
     {
-	  /* Socket doesn't implement si_recvmsg fallback to si_recvfrom */
-	  FAR void *buf             = msg->msg_iov->iov_base;
-	  FAR struct sockaddr *from = msg->msg_name;
-	  FAR socklen_t *fromlen    = (FAR socklen_t *)&msg->msg_namelen;
-	  size_t len                = msg->msg_iov->iov_len;
-	  return psock->s_sockif->si_recvfrom(psock, buf, len, flags, from, fromlen);
+	  /* Socket doesn't implement si_sendmsg fallback to si_sendto */
+	  FAR void *buf           = msg->msg_iov->iov_base;
+	  FAR struct sockaddr *to = msg->msg_name;
+	  socklen_t tolen         = msg->msg_namelen;
+	  size_t len              = msg->msg_iov->iov_len;
+	  return psock->s_sockif->si_sendto(psock, buf, len, flags, to, tolen);
     }
 
 }
 
 /****************************************************************************
- * Name: nx_recvfrom
+ * Name: nx_sendfrom
  *
  * Description:
- *   nx_recvfrom() receives messages from a socket, and may be used to
+ *   nx_sendfrom() receives messages from a socket, and may be used to
  *   receive data on a socket whether or not it is connection-oriented.
  *   This is an internal OS interface.  It is functionally equivalent to
- *   recvfrom() except that:
+ *   sendfrom() except that:
  *
  *   - It is not a cancellation point, and
  *   - It does not modify the errno variable.
@@ -148,13 +148,13 @@ ssize_t psock_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg,
  * Returned Value:
  *   On success, returns the number of characters sent.  If no data is
  *   available to be received and the peer has performed an orderly shutdown,
- *   recv() will return 0.  Otherwise, on any failure, a negated errno value
+ *   send() will return 0.  Otherwise, on any failure, a negated errno value
  *   is returned (see comments with send() for a list of appropriate errno
  *   values).
  *
  ****************************************************************************/
 
-ssize_t nx_recvmsg(int sockfd, FAR struct msghdr *msg, int flags)
+ssize_t nx_sendmsg(int sockfd, FAR struct msghdr *msg, int flags)
 {
   FAR struct socket *psock;
 
@@ -162,16 +162,16 @@ ssize_t nx_recvmsg(int sockfd, FAR struct msghdr *msg, int flags)
 
   psock = sockfd_socket(sockfd);
 
-  /* Then let psock_recvmsg() do all of the work */
+  /* Then let psock_sendmsg() do all of the work */
 
-  return psock_recvmsg(psock, msg, flags);
+  return psock_sendmsg(psock, msg, flags);
 }
 
 /****************************************************************************
- * Function: recvmsg
+ * Function: sendmsg
  *
  * Description:
- *   The recvmsg() call is identical to recvfrom() with a NULL from parameter.
+ *   The sendmsg() call is identical to sendfrom() with a NULL from parameter.
  *
  * Parameters:
  *   sockfd   Socket descriptor of socket
@@ -209,12 +209,12 @@ ssize_t nx_recvmsg(int sockfd, FAR struct msghdr *msg, int flags)
  *
  ****************************************************************************/
 
-ssize_t recvmsg(int sockfd, FAR struct msghdr *msg, int flags)
+ssize_t sendmsg(int sockfd, FAR struct msghdr *msg, int flags)
 {
   FAR struct socket *psock;
   ssize_t ret;
 
-  /* recvfrom() is a cancellation point */
+  /* sendfrom() is a cancellation point */
 
   enter_cancellation_point();
 
@@ -222,9 +222,9 @@ ssize_t recvmsg(int sockfd, FAR struct msghdr *msg, int flags)
 
   psock = sockfd_socket(sockfd);
 
-  /* Let psock_recvfrom() do all of the work */
+  /* Let psock_sendfrom() do all of the work */
 
-  ret = psock_recvmsg(psock, msg, flags);
+  ret = psock_sendmsg(psock, msg, flags);
   if (ret < 0)
     {
       _SO_SETERRNO(psock, -ret);
@@ -235,4 +235,4 @@ ssize_t recvmsg(int sockfd, FAR struct msghdr *msg, int flags)
   return ret;
 }
 
-#endif /* CONFIG_NET_RECVMSG_CMSG */
+#endif /* CONFIG_NET_CMSG */


[incubator-nuttx] 26/31: Code style fixes 4

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch SocketCAN
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 437d3d49a48562163959b4a9a64f063b1551459f
Author: Jari van Ewijk <ja...@nxp.com>
AuthorDate: Mon Mar 16 09:03:03 2020 +0100

    Code style fixes 4
---
 include/nuttx/net/net.h            | 12 +++---
 net/can/can_setsockopt.c           | 40 +++++++++++-------
 net/devif/devif.h                  | 87 ++++++++++++++++++++------------------
 net/devif/devif_poll.c             | 37 +++++++++-------
 net/icmp/icmp_sockif.c             | 14 +++---
 net/icmpv6/icmpv6_sockif.c         | 28 ++++++------
 net/ieee802154/ieee802154_sockif.c | 47 +++++++++++---------
 net/local/local_sockif.c           |  8 ++--
 net/netlink/netlink_sockif.c       | 15 +++++++
 net/socket/recvmsg.c               | 44 ++++++++++---------
 net/socket/sendmsg.c               | 43 ++++++++++---------
 net/socket/setsockopt.c            |  3 +-
 12 files changed, 216 insertions(+), 162 deletions(-)

diff --git a/include/nuttx/net/net.h b/include/nuttx/net/net.h
index 055c865..47de1f8 100644
--- a/include/nuttx/net/net.h
+++ b/include/nuttx/net/net.h
@@ -215,9 +215,11 @@ struct sock_intf_s
   CODE ssize_t    (*si_recvfrom)(FAR struct socket *psock, FAR void *buf,
                     size_t len, int flags, FAR struct sockaddr *from,
                     FAR socklen_t *fromlen);
-#ifdef CONFIG_NET_RECVMSG_CMSG
+#ifdef CONFIG_NET_CMSG
   CODE ssize_t    (*si_recvmsg)(FAR struct socket *psock,
-		            FAR struct msghdr *msg, int flags);
+    FAR struct msghdr *msg, int flags);
+  CODE ssize_t    (*si_sendmsg)(FAR struct socket *psock,
+    FAR struct msghdr *msg, int flags);
 #endif
   CODE int        (*si_close)(FAR struct socket *psock);
 #ifdef CONFIG_NET_USRSOCK
@@ -507,9 +509,9 @@ FAR struct iob_s *net_ioballoc(bool throttled, enum iob_user_e consumerid);
  * Description:
  *   Check if the socket descriptor is valid for the provided TCB and if it
  *   supports the requested access.  This trivial operation is part of the
- *   fdopen() operation when the fdopen() is performed on a socket descriptor.
- *   It simply performs some sanity checking before permitting the socket
- *   descriptor to be wrapped as a C FILE stream.
+ *   fdopen() operation when the fdopen() is performed on a socket
+ *   descriptor.  It simply performs some sanity checking before permitting
+ *   the socket descriptor to be wrapped as a C FILE stream.
  *
  ****************************************************************************/
 
diff --git a/net/can/can_setsockopt.c b/net/can/can_setsockopt.c
index ac9f912..3359e40 100644
--- a/net/can/can_setsockopt.c
+++ b/net/can/can_setsockopt.c
@@ -121,40 +121,48 @@ int can_setsockopt(FAR struct socket *psock, int option,
         break;
 
       case CAN_RAW_LOOPBACK:
-    if (value_len != sizeof(conn->loopback))
-      return -EINVAL;
+        if (value_len != sizeof(conn->loopback))
+          {
+            return -EINVAL;
+          }
 
-    conn->loopback = *(FAR int32_t *)value;
+        conn->loopback = *(FAR int32_t *)value;
 
-    break;
+        break;
 
       case CAN_RAW_RECV_OWN_MSGS:
-    if (value_len != sizeof(conn->recv_own_msgs))
-      return -EINVAL;
+        if (value_len != sizeof(conn->recv_own_msgs))
+          {
+            return -EINVAL;
+          }
 
-    conn->recv_own_msgs = *(FAR int32_t *)value;
+        conn->recv_own_msgs = *(FAR int32_t *)value;
 
-    break;
+        break;
 
       case CAN_RAW_FD_FRAMES:
-    if (value_len != sizeof(conn->fd_frames))
-      return -EINVAL;
+        if (value_len != sizeof(conn->fd_frames))
+          {
+            return -EINVAL;
+          }
 
-    conn->fd_frames = *(FAR int32_t *)value;
+          conn->fd_frames = *(FAR int32_t *)value;
 
-    break;
+          break;
 
       case CAN_RAW_JOIN_FILTERS:
         break;
 
 #ifdef CONFIG_NET_CAN_RAW_TX_DEADLINE
       case CAN_RAW_TX_DEADLINE:
-  		if (value_len != sizeof(conn->tx_deadline))
-  			return -EINVAL;
+        if (value_len != sizeof(conn->tx_deadline))
+          {
+            return -EINVAL;
+          }
 
-  		conn->tx_deadline = *(FAR int32_t *)value;
+        conn->tx_deadline = *(FAR int32_t *)value;
 
-  		break;
+        break;
 #endif
 
       default:
diff --git a/net/devif/devif.h b/net/devif/devif.h
index f924ebc..1a95011 100644
--- a/net/devif/devif.h
+++ b/net/devif/devif.h
@@ -68,31 +68,32 @@
  *
  *   TCP_ACKDATA      IN: Signifies that the outstanding data was ACKed and
  *                        the socket layer should send out new data instead
- *                        of retransmitting the last data (TCP only)
+ *                        of retransmitting the last data. (TCP only)
  *                   OUT: Input state must be preserved on output.
  *
  *   TCP_NEWDATA      IN: Set to indicate that the peer has sent us new data.
- *   UDP_NEWDATA     OUT: Cleared (only) by the socket layer logic to indicate
- *   ICMP_NEWDATA         that the new data was consumed, suppressing further
- *   ICMPv6_NEWDATA       attempts to process the new data.
- *   PKT_NEWDATA
+ *   UDP_NEWDATA     OUT: Cleared (only) by the socket layer logic to
+ *   ICMP_NEWDATA         indicate that the new data was consumed,
+ *   ICMPv6_NEWDATA       suppressing further attempts to process the new
+ *   PKT_NEWDATA          data.
  *   BLUETOOTH_NEWDATA
  *   IEEE802154_NEWDATA
  *
  *   TCP_SNDACK       IN: Not used; always zero
- *                   OUT: Set by the socket layer if the new data was consumed
- *                        and an ACK should be sent in the response. (TCP only)
+ *                   OUT: Set by the socket layer if the new data was
+ *                        consumed and an ACK should be sent in the response.
+ *                        (TCP only)
  *
  *   TCP_REXMIT       IN: Tells the socket layer to retransmit the data that
  *                        was last sent. (TCP only)
  *                   OUT: Not used
  *
- *   TCP_POLL        IN:  Used for polling the socket layer.  This is provided
- *   UDP_POLL             periodically from the drivers to support (1) timed
- *   PKT_POLL             operations, and (2) to check if the socket layer has
- *   BLUETOOTH_POLL       data that it wants to send.  These are socket oriented
- *   IEEE802154_POLL      callbacks where the context depends on the specific
- *                        set
+ *   TCP_POLL        IN:  Used for polling the socket layer.  This is
+ *   UDP_POLL             provided periodically from the drivers to support
+ *   PKT_POLL             (1) timed operations, and (2) to check if the
+ *   BLUETOOTH_POLL       socket layer has data that it wants to send.
+ *   IEEE802154_POLL      These are socket oriented callbacks where the
+ *                        context depends on the specific set.
  *                   OUT: Not used
  *
  *   TCP_BACKLOG      IN: There is a new connection in the backlog list set
@@ -104,14 +105,15 @@
  *                   OUT: The socket layer signals that it wants to close the
  *                        connection. (TCP only)
  *
- *   TCP_ABORT        IN: The remote host has aborted the connection, thus the
- *                        connection has gone away. (TCP only)
+ *   TCP_ABORT        IN: The remote host has aborted the connection, thus
+ *                        the connection has gone away. (TCP only)
  *                   OUT: The socket layer signals that it wants to abort the
  *                        connection. (TCP only)
  *
- *   TCP_CONNECTED    IN: We have got a connection from a remote host and have
- *                        set up a new connection for it, or an active connection
- *                        has been successfully established. (TCP only)
+ *   TCP_CONNECTED    IN: We have got a connection from a remote host and
+ *                        have set up a new connection for it, or an active
+ *                        connection has been successfully established.
+ *                        (TCP only)
  *                   OUT: Not used
  *
  *   TCP_TIMEDOUT     IN: The connection has been aborted due to too many
@@ -121,37 +123,38 @@
  * Device Specific Events:  These are events that may be notified through
  * callback lists residing in the network device structure.
  *
- *   ARP_POLL         IN: Used for polling the socket layer.  This is provided
- *                        periodically from the drivers to support (1) timed
- *                        operations, and (2) to check if the ARP layer needs
- *                        to send an ARP request.  This is a device oriented
- *                        event, not associated with a socket.
+ *   ARP_POLL         IN: Used for polling the socket layer.  This is
+ *                        provided periodically from the drivers to support
+ *                        (1) timed operations, and (2) to check if the ARP
+ *                        layer needs to send an ARP request.  This is a
+ *                        device oriented event, not associated with a
+ *                        socket.
  *                   OUT: Not used
  *
- *   ICMP_POLL        IN: Used for polling the socket layer.  This is provided
- *                        periodically from the drivers to support (1) timed
- *                        operations, and (2) to check if the ICMP layer needs
- *                        to send an ARP request.  This is a device oriented
- *                        event, not associated with a socket.  This differs
- *                        from ICMPv6_POLL only in that the appdata pointer
- *                        is set differently
+ *   ICMP_POLL        IN: Used for polling the socket layer.  This is
+ *                        provided periodically from the drivers to support
+ *                        (1) timed operations, and (2) to check if the ICMP
+ *                        layer needs to send an ARP request.  This is a
+ *                        device oriented event, not associated with a
+ *                        socket.  This differs from ICMPv6_POLL only in that
+ *                        the appdata pointer is set differently.
  *                   OUT: Not used
  *
- *   ICMPv6_POLL      IN: Used for polling the socket layer.  This is provided
- *                        periodically from the drivers to support (1) timed
- *                        operations, and (2) to check if the ICMP layer needs
- *                        to send an ARP request.  This is a device oriented
- *                        event, not associated with a socket.  This differs
- *                        from ICMP_POLL only in that the appdata pointer
- *                        is set differently
+ *   ICMPv6_POLL      IN: Used for polling the socket layer.  This is
+ *                        provided periodically from the drivers to support
+ *                        (1) timed operations, and (2) to check if the ICMP
+ *                        layer needs to send an ARP request.  This is a
+ *                        device oriented event, not associated with a
+ *                        socket.  This differs from ICMP_POLL only in that
+ *                        the appdata pointer is set differently.
  *                   OUT: Not used
  *
  *   IPFWD_POLL       IN: Used for polling for forwarded packets layer.  This
- *                        is provided periodically from the drivers to support
- *                        to check if there is a packet waiting to be forward
- *                        on the device.  This is a device oriented event,
- *                        not associated with a socket.  The appdata pointer
- *                        The appdata pointer is not used in this case.
+ *                        is provided periodically from the drivers to
+ *                        support to check if there is a packet waiting to be
+ *                        forward on the device.  This is a device oriented
+ *                        event, not associated with a socket.  The appdata
+ *                        pointer is not used in this case.
  *                   OUT: Not used
  *
  *   NETDEV_DOWN:     IN: The network device has been taken down.
diff --git a/net/devif/devif_poll.c b/net/devif/devif_poll.c
index e997a6f..803d741 100644
--- a/net/devif/devif_poll.c
+++ b/net/devif/devif_poll.c
@@ -173,15 +173,17 @@ static void devif_packet_conversion(FAR struct net_driver_s *dev,
                 }
               else
                 {
-                  nerr("ERROR: ICMPv6 protocol error: %u...  Packet dropped\n",
-                       ipv6->proto);
+                  nerr(
+                    "ERROR: ICMPv6 protocol error: %u...  Packet dropped\n",
+                    ipv6->proto);
                 }
             }
           else
 #endif
             {
-              nerr("ERROR: Unhandled packet dropped.  pkttype=%u protocol=%u\n",
-                    pkttype, ipv6->proto);
+              nerr(
+                "ERROR: Unhandled packet dropped.  pkttype=%u protocol=%u\n",
+                pkttype, ipv6->proto);
             }
 
           UNUSED(ipv6);
@@ -396,14 +398,16 @@ static inline int devif_poll_icmpv6(FAR struct net_driver_s *dev,
   FAR struct icmpv6_conn_s *conn = NULL;
   int bstop = 0;
 
-  /* Traverse all of the allocated ICMPV6 connections and perform the poll action */
+  /* Traverse all of the allocated ICMPV6 connections and perform
+   * the poll action
+   */
 
   do
     {
       /* Perform the ICMPV6 poll
-       * Note: conn equal NULL in the first iteration means poll dev's callback list
-       * since icmpv6_autoconfig and icmpv6_neighbor still append it's callback into
-       * this list.
+       * Note: conn equal NULL in the first iteration means poll dev's
+       * callback list since icmpv6_autoconfig and icmpv6_neighbor still
+       * append it's callback into this list.
        */
 
       icmpv6_poll(dev, conn);
@@ -654,9 +658,9 @@ static inline int devif_poll_tcp_timer(FAR struct net_driver_s *dev,
  *   should do only if it cannot accept further write data).
  *
  *   When the callback function is called, there may be an outbound packet
- *   waiting for service in the device packet buffer, and if so the d_len field
- *   is set to a value larger than zero. The device driver should then send
- *   out the packet.
+ *   waiting for service in the device packet buffer, and if so the d_len
+ *   field is set to a value larger than zero. The device driver should then
+ *   send out the packet.
  *
  * Assumptions:
  *   This function is called from the MAC device driver with the network
@@ -690,6 +694,7 @@ int devif_poll(FAR struct net_driver_s *dev, devif_poll_callback_t callback)
 #ifdef CONFIG_NET_CAN
     {
       /* Check for pending packet socket transfer */
+
       bstop = devif_poll_can_connections(dev, callback);
     }
 
@@ -791,8 +796,8 @@ int devif_poll(FAR struct net_driver_s *dev, devif_poll_callback_t callback)
  * Name: devif_timer
  *
  * Description:
- *   These function will traverse each active network connection structure and
- *   perform network timer operations. The Ethernet driver MUST implement
+ *   These function will traverse each active network connection structure
+ *   and perform network timer operations. The Ethernet driver MUST implement
  *   logic to periodically call devif_timer().
  *
  *   This function will call the provided callback function for every active
@@ -801,9 +806,9 @@ int devif_poll(FAR struct net_driver_s *dev, devif_poll_callback_t callback)
  *   should do only if it cannot accept further write data).
  *
  *   When the callback function is called, there may be an outbound packet
- *   waiting for service in the device packet buffer, and if so the d_len field
- *   is set to a value larger than zero. The device driver should then send
- *   out the packet.
+ *   waiting for service in the device packet buffer, and if so the d_len
+ *   field is set to a value larger than zero. The device driver should then
+ *   send out the packet.
  *
  * Assumptions:
  *   This function is called from the MAC device driver with the network
diff --git a/net/icmp/icmp_sockif.c b/net/icmp/icmp_sockif.c
index ebe2bab..2b1e179 100644
--- a/net/icmp/icmp_sockif.c
+++ b/net/icmp/icmp_sockif.c
@@ -284,7 +284,8 @@ static int icmp_connect(FAR struct socket *psock,
  * Input Parameters:
  *   psock    Reference to the listening socket structure
  *   addr     Receives the address of the connecting client
- *   addrlen  Input: allocated size of 'addr', Return: returned size of 'addr'
+ *   addrlen  Input: allocated size of 'addr',
+ *            Return: returned size of 'addr'
  *   newsock  Location to return the accepted socket information.
  *
  * Returned Value:
@@ -322,7 +323,8 @@ static int icmp_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
  *
  ****************************************************************************/
 
-static int icmp_bind(FAR struct socket *psock, FAR const struct sockaddr *addr,
+static int icmp_bind(FAR struct socket *psock,
+                     FAR const struct sockaddr *addr,
                      socklen_t addrlen)
 {
   /* An ICMP socket cannot be bound to a local address */
@@ -368,10 +370,10 @@ static int icmp_getsockname(FAR struct socket *psock,
  * Name: icmp_getpeername
  *
  * Description:
- *   The icmp_getpeername() function retrieves the remote-connected name of the
- *   specified packet socket, stores this address in the sockaddr structure
- *   pointed to by the 'addr' argument, and stores the length of this
- *   address in the object pointed to by the 'addrlen' argument.
+ *   The icmp_getpeername() function retrieves the remote-connected name of
+ *   the specified packet socket, stores this address in the sockaddr
+ *   structure pointed to by the 'addr' argument, and stores the length of
+ *   this address in the object pointed to by the 'addrlen' argument.
  *
  *   If the actual length of the address is greater than the length of the
  *   supplied sockaddr structure, the stored address will be truncated.
diff --git a/net/icmpv6/icmpv6_sockif.c b/net/icmpv6/icmpv6_sockif.c
index 5adae60..3dbb5c8 100644
--- a/net/icmpv6/icmpv6_sockif.c
+++ b/net/icmpv6/icmpv6_sockif.c
@@ -284,7 +284,8 @@ static int icmpv6_connect(FAR struct socket *psock,
  * Input Parameters:
  *   psock    Reference to the listening socket structure
  *   addr     Receives the address of the connecting client
- *   addrlen  Input: allocated size of 'addr', Return: returned size of 'addr'
+ *   addrlen  Input: allocated size of 'addr',
+ *            Return: returned size of 'addr'
  *   newsock  Location to return the accepted socket information.
  *
  * Returned Value:
@@ -322,8 +323,9 @@ static int icmpv6_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
  *
  ****************************************************************************/
 
-static int icmpv6_bind(FAR struct socket *psock, FAR const struct sockaddr *addr,
-                     socklen_t addrlen)
+static int icmpv6_bind(FAR struct socket *psock,
+                       FAR const struct sockaddr *addr,
+                       socklen_t addrlen)
 {
   /* An ICMPv6 socket cannot be bound to a local address */
 
@@ -334,10 +336,10 @@ static int icmpv6_bind(FAR struct socket *psock, FAR const struct sockaddr *addr
  * Name: icmpv6_getsockname
  *
  * Description:
- *   The icmpv6_getsockname() function retrieves the locally-bound name of the
- *   specified packet socket, stores this address in the sockaddr structure
- *   pointed to by the 'addr' argument, and stores the length of this
- *   address in the object pointed to by the 'addrlen' argument.
+ *   The icmpv6_getsockname() function retrieves the locally-bound name of
+ *   the specified packet socket, stores this address in the sockaddr
+ *   structure pointed to by the 'addr' argument, and stores the length of
+ *   this address in the object pointed to by the 'addrlen' argument.
  *
  *   If the actual length of the address is greater than the length of the
  *   supplied sockaddr structure, the stored address will be truncated.
@@ -368,10 +370,10 @@ static int icmpv6_getsockname(FAR struct socket *psock,
  * Name: icmpv6_getpeername
  *
  * Description:
- *   The icmpv6_getpeername() function retrieves the remote-connected name of the
- *   specified packet socket, stores this address in the sockaddr structure
- *   pointed to by the 'addr' argument, and stores the length of this
- *   address in the object pointed to by the 'addrlen' argument.
+ *   The icmpv6_getpeername() function retrieves the remote-connected name of
+ *   the specified packet socket, stores this address in the sockaddr
+ *   structure pointed to by the 'addr' argument, and stores the length of
+ *   this address in the object pointed to by the 'addrlen' argument.
  *
  *   If the actual length of the address is greater than the length of the
  *   supplied sockaddr structure, the stored address will be truncated.
@@ -487,8 +489,8 @@ static int icmpv6_netpoll(FAR struct socket *psock, FAR struct pollfd *fds,
 static ssize_t icmpv6_send(FAR struct socket *psock, FAR const void *buf,
                         size_t len, int flags)
 {
-  /* ICMPv6 sockets cannot be bound and, hence, cannot support any connection-
-   * oriented data transfer.
+  /* ICMPv6 sockets cannot be bound and, hence, cannot support any
+   * connection-oriented data transfer.
    */
 
   return -EDESTADDRREQ;
diff --git a/net/ieee802154/ieee802154_sockif.c b/net/ieee802154/ieee802154_sockif.c
index 6c0f88a..03db4fb 100644
--- a/net/ieee802154/ieee802154_sockif.c
+++ b/net/ieee802154/ieee802154_sockif.c
@@ -245,10 +245,10 @@ static void ieee802154_addref(FAR struct socket *psock)
  * Name: ieee802154_connect
  *
  * Description:
- *   ieee802154_connect() connects the local socket referred to by the structure
- *   'psock' to the address specified by 'addr'. The addrlen argument
- *   specifies the size of 'addr'.  The format of the address in 'addr' is
- *   determined by the address space of the socket 'psock'.
+ *   ieee802154_connect() connects the local socket referred to by the
+ *   structure 'psock' to the address specified by 'addr'. The addrlen
+ *   argument specifies the size of 'addr'.  The format of the address in
+ *   'addr' is determined by the address space of the socket 'psock'.
  *
  *   If the socket 'psock' is of type SOCK_DGRAM then 'addr' is the address
  *   to which datagrams are sent by default, and the only address from which
@@ -311,8 +311,8 @@ static int ieee802154_connect(FAR struct socket *psock,
  * Name: ieee802154_accept
  *
  * Description:
- *   The ieee802154_accept function is used with connection-based socket types
- *   (SOCK_STREAM, SOCK_SEQPACKET and SOCK_RDM). It extracts the first
+ *   The ieee802154_accept function is used with connection-based socket
+ *   types (SOCK_STREAM, SOCK_SEQPACKET and SOCK_RDM). It extracts the first
  *   connection request on the queue of pending connections, creates a new
  *   connected socket with mostly the same properties as 'sockfd', and
  *   allocates a new socket descriptor for the socket, which is returned. The
@@ -338,7 +338,8 @@ static int ieee802154_connect(FAR struct socket *psock,
  * Input Parameters:
  *   psock    Reference to the listening socket structure
  *   addr     Receives the address of the connecting client
- *   addrlen  Input: allocated size of 'addr', Return: returned size of 'addr'
+ *   addrlen  Input: allocated size of 'addr',
+ *            Return: returned size of 'addr'
  *   newsock  Location to return the accepted socket information.
  *
  * Returned Value:
@@ -380,7 +381,8 @@ static int ieee802154_accept(FAR struct socket *psock,
  ****************************************************************************/
 
 static int ieee802154_bind(FAR struct socket *psock,
-                           FAR const struct sockaddr *addr, socklen_t addrlen)
+                           FAR const struct sockaddr *addr,
+                           socklen_t addrlen)
 {
   FAR const struct sockaddr_ieee802154_s *iaddr;
   FAR struct radio_driver_s *radio;
@@ -450,10 +452,10 @@ static int ieee802154_bind(FAR struct socket *psock,
  * Name: ieee802154_getsockname
  *
  * Description:
- *   The ieee802154_getsockname() function retrieves the locally-bound name of the
- *   specified packet socket, stores this address in the sockaddr structure
- *   pointed to by the 'addr' argument, and stores the length of this
- *   address in the object pointed to by the 'addrlen' argument.
+ *   The ieee802154_getsockname() function retrieves the locally-bound name
+ *   of the specified packet socket, stores this address in the sockaddr
+ *   structure pointed to by the 'addr' argument, and stores the length of
+ *   this address in the object pointed to by the 'addrlen' argument.
  *
  *   If the actual length of the address is greater than the length of the
  *   supplied sockaddr structure, the stored address will be truncated.
@@ -512,10 +514,10 @@ static int ieee802154_getsockname(FAR struct socket *psock,
  * Name: ieee802154_getpeername
  *
  * Description:
- *   The ieee802154_getpeername() function retrieves the remote-connectd name of the
- *   specified packet socket, stores this address in the sockaddr structure
- *   pointed to by the 'addr' argument, and stores the length of this
- *   address in the object pointed to by the 'addrlen' argument.
+ *   The ieee802154_getpeername() function retrieves the remote-connectd name
+ *   of the specified packet socket, stores this address in the sockaddr
+ *   structure pointed to by the 'addr' argument, and stores the length of
+ *   this address in the object pointed to by the 'addrlen' argument.
  *
  *   If the actual length of the address is greater than the length of the
  *   supplied sockaddr structure, the stored address will be truncated.
@@ -680,7 +682,8 @@ static ssize_t ieee802154_send(FAR struct socket *psock, FAR const void *buf,
 
           ret = psock_ieee802154_sendto(psock, buf, len, flags,
                                         (FAR const struct sockaddr *)&to,
-                                        sizeof(struct sockaddr_ieee802154_s));
+                                        sizeof(
+                                          struct sockaddr_ieee802154_s));
         }
     }
   else
@@ -717,9 +720,11 @@ static ssize_t ieee802154_send(FAR struct socket *psock, FAR const void *buf,
  *
  ****************************************************************************/
 
-static ssize_t ieee802154_sendto(FAR struct socket *psock, FAR const void *buf,
+static ssize_t ieee802154_sendto(FAR struct socket *psock,
+                                 FAR const void *buf,
                                  size_t len, int flags,
-                                 FAR const struct sockaddr *to, socklen_t tolen)
+                                 FAR const struct sockaddr *to,
+                                 socklen_t tolen)
 {
   ssize_t ret;
 
@@ -777,8 +782,8 @@ static int ieee802154_close(FAR struct socket *psock)
             {
               /* Yes... free the connection structure */
 
-              conn->crefs = 0;          /* No more references on the connection */
-              ieee802154_conn_free(psock->s_conn);  /* Free network resources */
+              conn->crefs = 0;                     /* No more references on the connection */
+              ieee802154_conn_free(psock->s_conn); /* Free network resources */
             }
           else
             {
diff --git a/net/local/local_sockif.c b/net/local/local_sockif.c
index cd9bd66..c4f7531 100644
--- a/net/local/local_sockif.c
+++ b/net/local/local_sockif.c
@@ -165,7 +165,8 @@ static int local_sockif_alloc(FAR struct socket *psock)
  *   specific socket fields.
  *
  * Input Parameters:
- *   psock    A pointer to a user allocated socket structure to be initialized.
+ *   psock    A pointer to a user allocated socket structure
+ *            to be initialized.
  *   protocol (see sys/socket.h)
  *
  * Returned Value:
@@ -594,7 +595,8 @@ static int local_connect(FAR struct socket *psock,
  * Input Parameters:
  *   psock    Reference to the listening socket structure
  *   addr     Receives the address of the connecting client
- *   addrlen  Input: allocated size of 'addr', Return: returned size of 'addr'
+ *   addrlen  Input: allocated size of 'addr',
+ *            Return: returned size of 'addr'
  *   newsock  Location to return the accepted socket information.
  *
  * Returned Value:
@@ -721,7 +723,7 @@ static ssize_t local_send(FAR struct socket *psock, FAR const void *buf,
  * Name: local_sendto
  *
  * Description:
- *   Implements the sendto() operation for the case of the local, Unix socket.
+ *   Implements the sendto() operation for the case of the local Unix socket.
  *
  * Input Parameters:
  *   psock    A pointer to a NuttX-specific, internal socket structure
diff --git a/net/netlink/netlink_sockif.c b/net/netlink/netlink_sockif.c
index 34b011a..5e05f64 100644
--- a/net/netlink/netlink_sockif.c
+++ b/net/netlink/netlink_sockif.c
@@ -510,8 +510,13 @@ static int netlink_connect(FAR struct socket *psock,
  ****************************************************************************/
 
 static int netlink_accept(FAR struct socket *psock,
+<<<<<<< HEAD
                           FAR struct sockaddr *addr, FAR socklen_t *addrlen,
                           FAR struct socket *newsock)
+=======
+                          FAR struct sockaddr *addr,
+                          FAR socklen_t *addrlen, FAR struct socket *newsock)
+>>>>>>> Code style fixes 4
 {
   return -EOPNOTSUPP;
 }
@@ -649,8 +654,13 @@ static int netlink_poll(FAR struct socket *psock, FAR struct pollfd *fds,
           conn->pollsem    = fds->sem;
           conn->pollevent  = &fds->revents;
 
+<<<<<<< HEAD
           ret = netlink_notifier_setup(netlink_response_available,
                                        conn, conn);
+=======
+          ret = netlink_notifier_setup(netlink_response_available, conn,
+                                       conn);
+>>>>>>> Code style fixes 4
           if (ret < 0)
             {
               nerr("ERROR: netlink_notifier_setup() failed: %d\n", ret);
@@ -729,7 +739,12 @@ static ssize_t netlink_send(FAR struct socket *psock, FAR const void *buf,
  *   returned when the socket was not actually connected.
  *
  * Input Parameters:
+<<<<<<< HEAD
  *   psock    A reference to the structure of the socket to be connected
+=======
+ *   psock    A reference to the socket structure of the socket
+ *            to be connected
+>>>>>>> Code style fixes 4
  *   buf      Data to send
  *   len      Length of data to send
  *   flags    Send flags (ignored)
diff --git a/net/socket/recvmsg.c b/net/socket/recvmsg.c
index 800eeb1..9ba5de3 100644
--- a/net/socket/recvmsg.c
+++ b/net/socket/recvmsg.c
@@ -1,7 +1,8 @@
 /****************************************************************************
  * net/socket/recvmsg.c
  *
- *   Copyright (C) 2007-2009, 2011-2017, 2019 Gregory Nutt. All rights reserved.
+ *   Copyright (C) 2007-2009, 2011-2017, 2019 Gregory Nutt. All rights
+ *     reserved.
  *   Author: Gregory Nutt <gn...@nuttx.org>
  *
  * Redistribution and use in source and binary forms, with or without
@@ -86,6 +87,7 @@ ssize_t psock_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg,
                        int flags)
 {
   /* Verify that non-NULL pointers were passed */
+
   if (msg == NULL)
     {
       return -EINVAL;
@@ -111,20 +113,22 @@ ssize_t psock_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg,
               (psock->s_sockif->si_recvmsg != NULL ||
                psock->s_sockif->si_recvfrom != NULL));
 
-  if(psock->s_sockif->si_recvmsg != NULL)
+  if (psock->s_sockif->si_recvmsg != NULL)
     {
-	  return psock->s_sockif->si_recvmsg(psock, msg, flags);
+      return psock->s_sockif->si_recvmsg(psock, msg, flags);
     }
   else
     {
-	  /* Socket doesn't implement si_recvmsg fallback to si_recvfrom */
-	  FAR void *buf             = msg->msg_iov->iov_base;
-	  FAR struct sockaddr *from = msg->msg_name;
-	  FAR socklen_t *fromlen    = (FAR socklen_t *)&msg->msg_namelen;
-	  size_t len                = msg->msg_iov->iov_len;
-	  return psock->s_sockif->si_recvfrom(psock, buf, len, flags, from, fromlen);
-    }
+      /* Socket doesn't implement si_recvmsg fallback to si_recvfrom */
 
+      FAR void *buf             = msg->msg_iov->iov_base;
+      FAR struct sockaddr *from = msg->msg_name;
+      FAR socklen_t *fromlen    = (FAR socklen_t *)&msg->msg_namelen;
+      size_t len                = msg->msg_iov->iov_len;
+
+      return psock->s_sockif->si_recvfrom(psock, buf, len, flags, from,
+                                          fromlen);
+    }
 }
 
 /****************************************************************************
@@ -171,7 +175,8 @@ ssize_t nx_recvmsg(int sockfd, FAR struct msghdr *msg, int flags)
  * Function: recvmsg
  *
  * Description:
- *   The recvmsg() call is identical to recvfrom() with a NULL from parameter.
+ *   The recvmsg() call is identical to recvfrom() with a NULL from
+ *   parameter.
  *
  * Parameters:
  *   sockfd   Socket descriptor of socket
@@ -184,19 +189,20 @@ ssize_t nx_recvmsg(int sockfd, FAR struct msghdr *msg, int flags)
  *   -1 is returned, and errno is set appropriately:
  *
  *   EAGAIN
- *     The socket is marked non-blocking and the receive operation would block,
- *     or a receive timeout had been set and the timeout expired before data
- *     was received.
+ *     The socket is marked non-blocking and the receive operation would
+ *     block, or a receive timeout had been set and the timeout expired
+ *     before data was received.
  *   EBADF
  *     The argument sockfd is an invalid descriptor.
  *   ECONNREFUSED
- *     A remote host refused to allow the network connection (typically because
- *     it is not running the requested service).
+ *     A remote host refused to allow the network connection (typically
+ *     because it is not running the requested service).
  *   EFAULT
- *     The receive buffer pointer(s) point outside the process's address space.
+ *     The receive buffer pointer(s) point outside the process's address
+ *     space.
  *   EINTR
- *     The receive was interrupted by delivery of a signal before any data were
- *     available.
+ *     The receive was interrupted by delivery of a signal before any data
+ *     were available.
  *   EINVAL
  *     Invalid argument passed.
  *   ENOMEM
diff --git a/net/socket/sendmsg.c b/net/socket/sendmsg.c
index 3bc32e8..a188b3a 100644
--- a/net/socket/sendmsg.c
+++ b/net/socket/sendmsg.c
@@ -1,7 +1,8 @@
 /****************************************************************************
  * net/socket/sendmsg.c
  *
- *   Copyright (C) 2007-2009, 2011-2017, 2019 Gregory Nutt. All rights reserved.
+ *   Copyright (C) 2007-2009, 2011-2017, 2019 Gregory Nutt. All rights
+ *     reserved.
  *   Author: Gregory Nutt <gn...@nuttx.org>
  *
  * Redistribution and use in source and binary forms, with or without
@@ -86,6 +87,7 @@ ssize_t psock_sendmsg(FAR struct socket *psock, FAR struct msghdr *msg,
                        int flags)
 {
   /* Verify that non-NULL pointers were passed */
+
   if (msg == NULL)
     {
       return -EINVAL;
@@ -111,20 +113,21 @@ ssize_t psock_sendmsg(FAR struct socket *psock, FAR struct msghdr *msg,
               (psock->s_sockif->si_sendmsg != NULL ||
                psock->s_sockif->si_sendto != NULL));
 
-  if(psock->s_sockif->si_sendmsg != NULL)
+  if (psock->s_sockif->si_sendmsg != NULL)
     {
-	  return psock->s_sockif->si_sendmsg(psock, msg, flags);
+      return psock->s_sockif->si_sendmsg(psock, msg, flags);
     }
   else
     {
-	  /* Socket doesn't implement si_sendmsg fallback to si_sendto */
-	  FAR void *buf           = msg->msg_iov->iov_base;
-	  FAR struct sockaddr *to = msg->msg_name;
-	  socklen_t tolen         = msg->msg_namelen;
-	  size_t len              = msg->msg_iov->iov_len;
-	  return psock->s_sockif->si_sendto(psock, buf, len, flags, to, tolen);
-    }
+      /* Socket doesn't implement si_sendmsg fallback to si_sendto */
 
+      FAR void *buf           = msg->msg_iov->iov_base;
+      FAR struct sockaddr *to = msg->msg_name;
+      socklen_t tolen         = msg->msg_namelen;
+      size_t len              = msg->msg_iov->iov_len;
+
+      return psock->s_sockif->si_sendto(psock, buf, len, flags, to, tolen);
+    }
 }
 
 /****************************************************************************
@@ -171,7 +174,8 @@ ssize_t nx_sendmsg(int sockfd, FAR struct msghdr *msg, int flags)
  * Function: sendmsg
  *
  * Description:
- *   The sendmsg() call is identical to sendfrom() with a NULL from parameter.
+ *   The sendmsg() call is identical to sendfrom() with a NULL from
+ *   parameter.
  *
  * Parameters:
  *   sockfd   Socket descriptor of socket
@@ -184,19 +188,20 @@ ssize_t nx_sendmsg(int sockfd, FAR struct msghdr *msg, int flags)
  *   -1 is returned, and errno is set appropriately:
  *
  *   EAGAIN
- *     The socket is marked non-blocking and the receive operation would block,
- *     or a receive timeout had been set and the timeout expired before data
- *     was received.
+ *     The socket is marked non-blocking and the receive operation would
+ *     block, or a receive timeout had been set and the timeout expired
+ *     before data was received.
  *   EBADF
  *     The argument sockfd is an invalid descriptor.
  *   ECONNREFUSED
- *     A remote host refused to allow the network connection (typically because
- *     it is not running the requested service).
+ *     A remote host refused to allow the network connection (typically
+ *     because it is not running the requested service).
  *   EFAULT
- *     The receive buffer pointer(s) point outside the process's address space.
+ *     The receive buffer pointer(s) point outside the process's address
+ *     space.
  *   EINTR
- *     The receive was interrupted by delivery of a signal before any data were
- *     available.
+ *     The receive was interrupted by delivery of a signal before any data
+ *     were available.
  *   EINVAL
  *     Invalid argument passed.
  *   ENOMEM
diff --git a/net/socket/setsockopt.c b/net/socket/setsockopt.c
index fddf0c1..873fcbc 100644
--- a/net/socket/setsockopt.c
+++ b/net/socket/setsockopt.c
@@ -283,7 +283,6 @@ static int psock_socketlevel_option(FAR struct socket *psock, int option,
 #ifdef CONFIG_NET_TIMESTAMP
       case SO_TIMESTAMP:  /* Generates a timestamp for each incoming packet */
         {
-
           /* Verify that option is at least the size of an integer. */
 
           if (value_len < sizeof(FAR int32_t))
@@ -297,7 +296,7 @@ static int psock_socketlevel_option(FAR struct socket *psock, int option,
 
           net_lock();
 
-          psock->s_timestamp = *((FAR int32_t*)value);
+          psock->s_timestamp = *((FAR int32_t *)value);
 
           net_unlock();
         }


[incubator-nuttx] 28/31: Made can/error.h nxstyle compliant

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch SocketCAN
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 7da69d5ce1f16ae7148d99b28cee221c429237eb
Author: Peter van der Perk <pe...@nxp.com>
AuthorDate: Wed Mar 18 09:13:34 2020 +0100

    Made can/error.h nxstyle compliant
---
 include/nuttx/can/error.h | 24 +++++++++++++-----------
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/include/nuttx/can/error.h b/include/nuttx/can/error.h
index d9c2396..cf5fec6 100644
--- a/include/nuttx/can/error.h
+++ b/include/nuttx/can/error.h
@@ -1,8 +1,10 @@
 /* SPDX-License-Identifier: ((GPL-2.0-only WITH Linux-syscall-note) OR BSD-3-Clause) */
-/*
+
+/************************************************************************************
  * linux/can/error.h
  *
- * Definitions of the CAN error messages to be filtered and passed to the user.
+ * Definitions of the CAN error messages to be filtered and passed to the
+ * user.
  *
  * Author: Oliver Hartkopp <ol...@volkswagen.de>
  * Copyright (c) 2002-2007 Volkswagen Group Electronic Research
@@ -40,7 +42,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  * DAMAGE.
- */
+ ************************************************************************************/
 
 #ifndef _UAPI_CAN_ERROR_H
 #define _UAPI_CAN_ERROR_H
@@ -94,18 +96,18 @@
 #define CAN_ERR_PROT_LOC_SRTR    0x04 /* substitute RTR (SFF: RTR) */
 #define CAN_ERR_PROT_LOC_IDE     0x05 /* identifier extension */
 #define CAN_ERR_PROT_LOC_ID17_13 0x07 /* ID bits 17-13 */
-#define CAN_ERR_PROT_LOC_ID12_05 0x0F /* ID bits 12-5 */
-#define CAN_ERR_PROT_LOC_ID04_00 0x0E /* ID bits 4-0 */
-#define CAN_ERR_PROT_LOC_RTR     0x0C /* RTR */
-#define CAN_ERR_PROT_LOC_RES1    0x0D /* reserved bit 1 */
+#define CAN_ERR_PROT_LOC_ID12_05 0x0f /* ID bits 12-5 */
+#define CAN_ERR_PROT_LOC_ID04_00 0x0e /* ID bits 4-0 */
+#define CAN_ERR_PROT_LOC_RTR     0x0c /* RTR */
+#define CAN_ERR_PROT_LOC_RES1    0x0d /* reserved bit 1 */
 #define CAN_ERR_PROT_LOC_RES0    0x09 /* reserved bit 0 */
-#define CAN_ERR_PROT_LOC_DLC     0x0B /* data length code */
-#define CAN_ERR_PROT_LOC_DATA    0x0A /* data section */
+#define CAN_ERR_PROT_LOC_DLC     0x0b /* data length code */
+#define CAN_ERR_PROT_LOC_DATA    0x0a /* data section */
 #define CAN_ERR_PROT_LOC_CRC_SEQ 0x08 /* CRC sequence */
 #define CAN_ERR_PROT_LOC_CRC_DEL 0x18 /* CRC delimiter */
 #define CAN_ERR_PROT_LOC_ACK     0x19 /* ACK slot */
-#define CAN_ERR_PROT_LOC_ACK_DEL 0x1B /* ACK delimiter */
-#define CAN_ERR_PROT_LOC_EOF     0x1A /* end of frame */
+#define CAN_ERR_PROT_LOC_ACK_DEL 0x1b /* ACK delimiter */
+#define CAN_ERR_PROT_LOC_EOF     0x1a /* end of frame */
 #define CAN_ERR_PROT_LOC_INTERM  0x12 /* intermission */
 
 /* error status of CAN-transceiver / data[4] */


[incubator-nuttx] 22/31: Code style fixes

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch SocketCAN
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 8b9e331d7349fde483984ce2256af38db7da5243
Author: Jari van Ewijk <ja...@nxp.com>
AuthorDate: Fri Mar 13 13:48:10 2020 +0100

    Code style fixes
---
 fs/vfs/fs_write.c         |  3 ++-
 include/netpacket/can.h   | 46 +++++++++++++++++++++++-----------------------
 include/nuttx/can/error.h | 10 ++++++----
 include/nuttx/mm/iob.h    |  6 ++++--
 include/nuttx/net/can.h   | 10 ++++------
 include/nuttx/net/net.h   |  2 +-
 6 files changed, 40 insertions(+), 37 deletions(-)

diff --git a/fs/vfs/fs_write.c b/fs/vfs/fs_write.c
index ef5f137..b48812e 100644
--- a/fs/vfs/fs_write.c
+++ b/fs/vfs/fs_write.c
@@ -86,7 +86,8 @@
  *
  ****************************************************************************/
 
-ssize_t file_write(FAR struct file *filep, FAR const void *buf, size_t nbytes)
+ssize_t file_write(FAR struct file *filep, FAR const void *buf,
+                   size_t nbytes)
 {
   FAR struct inode *inode;
 
diff --git a/include/netpacket/can.h b/include/netpacket/can.h
index 0b4c7b9..4ea2104 100644
--- a/include/netpacket/can.h
+++ b/include/netpacket/can.h
@@ -102,37 +102,37 @@ struct sockaddr_can
   sa_family_t can_family;
   int16_t     can_ifindex;
   union
-    {
-      /* Transport protocol class address information */
+  {
+    /* Transport protocol class address information */
 
-      struct
-      {
-        canid_t rx_id;
-        canid_t tx_id;
-      } tp;
+    struct
+    {
+      canid_t rx_id;
+      canid_t tx_id;
+    } tp;
 
-      /* J1939 address information */
+    /* J1939 address information */
 
-      struct
-      {
-        /* 8 byte name when using dynamic addressing */
+    struct
+    {
+      /* 8 byte name when using dynamic addressing */
 
-        uint64_t name;
+      uint64_t name;
 
-        /* pgn:
-         *   8 bit: PS in PDU2 case, else 0
-         *   8 bit: PF
-         *   1 bit: DP
-         *   1 bit: reserved
-         */
+      /* pgn:
+       *   8 bit: PS in PDU2 case, else 0
+       *   8 bit: PF
+       *   1 bit: DP
+       *   1 bit: reserved
+       */
 
-        uint32_t pgn;
+      uint32_t pgn;
 
-        /* 1 byte address */
+      /* 1 byte address */
 
-        uint8_t addr;
-      } j1939;
-    } can_addr;
+      uint8_t addr;
+    } j1939;
+  } can_addr;
 };
 
 #endif /* __INCLUDE_NETPACKET_CAN_H */
diff --git a/include/nuttx/can/error.h b/include/nuttx/can/error.h
index 3463328..d9c2396 100644
--- a/include/nuttx/can/error.h
+++ b/include/nuttx/can/error.h
@@ -60,7 +60,8 @@
 
 /* arbitration lost in bit ... / data[0] */
 #define CAN_ERR_LOSTARB_UNSPEC   0x00 /* unspecified */
-				      /* else bit number in bitstream */
+
+/* else bit number in bitstream */
 
 /* error status of CAN-controller / data[1] */
 #define CAN_ERR_CRTL_UNSPEC      0x00 /* unspecified */
@@ -70,8 +71,8 @@
 #define CAN_ERR_CRTL_TX_WARNING  0x08 /* reached warning level for TX errors */
 #define CAN_ERR_CRTL_RX_PASSIVE  0x10 /* reached error passive status RX */
 #define CAN_ERR_CRTL_TX_PASSIVE  0x20 /* reached error passive status TX */
-				      /* (at least one error counter exceeds */
-				      /* the protocol-defined level of 127)  */
+                                      /* (at least one error counter exceeds */
+                                      /* the protocol-defined level of 127)  */
 #define CAN_ERR_CRTL_ACTIVE      0x40 /* recovered to error active state */
 
 /* error in CAN protocol (type) / data[2] */
@@ -108,7 +109,8 @@
 #define CAN_ERR_PROT_LOC_INTERM  0x12 /* intermission */
 
 /* error status of CAN-transceiver / data[4] */
-/*                                             CANH CANL */
+
+                                            /* CANH CANL */
 #define CAN_ERR_TRX_UNSPEC             0x00 /* 0000 0000 */
 #define CAN_ERR_TRX_CANH_NO_WIRE       0x04 /* 0000 0100 */
 #define CAN_ERR_TRX_CANH_SHORT_TO_BAT  0x05 /* 0000 0101 */
diff --git a/include/nuttx/mm/iob.h b/include/nuttx/mm/iob.h
index e986105..32c0bfd 100644
--- a/include/nuttx/mm/iob.h
+++ b/include/nuttx/mm/iob.h
@@ -252,7 +252,8 @@ void iob_initialize(void);
  * Name: iob_alloc
  *
  * Description:
- *   Allocate an I/O buffer by taking the buffer at the head of the free list.
+ *   Allocate an I/O buffer by taking the buffer at the head of the free
+ *   list.
  *
  ****************************************************************************/
 
@@ -590,7 +591,8 @@ void iob_dump(FAR const char *msg, FAR struct iob_s *iob, unsigned int len,
  * Name: iob_getuserstats
  *
  * Description:
- *   Return a reference to the IOB usage statistics for the IOB consumer/producer
+ *   Return a reference to the IOB usage statistics for the IOB
+ *   consumer/producer
  *
  * Input Parameters:
  *   userid - id representing the IOB producer/consumer
diff --git a/include/nuttx/net/can.h b/include/nuttx/net/can.h
index d426c7b..9cda480 100644
--- a/include/nuttx/net/can.h
+++ b/include/nuttx/net/can.h
@@ -53,15 +53,15 @@
  * Pre-processor Definitions
  ****************************************************************************/
 
-#define CAN_HDRLEN 4 //FIXME standard id vs extended
-#define NET_CAN_PKTSIZE sizeof(struct canfd_frame) // max size we can send through socket
-//FIXME think about can & canfd support
+#define CAN_HDRLEN 4                               /* FIXME standard id vs extended */
+#define NET_CAN_PKTSIZE sizeof(struct canfd_frame) /* max size we can send through socket*/
+
+/* FIXME think about can & canfd support */
 
 /****************************************************************************
  * Public Types
  ****************************************************************************/
 
-
 /****************************************************************************
  * Public Data
  ****************************************************************************/
@@ -74,8 +74,6 @@ extern "C"
 #define EXTERN extern
 #endif
 
-
-
 /****************************************************************************
  * Public Function Prototypes
  ****************************************************************************/
diff --git a/include/nuttx/net/net.h b/include/nuttx/net/net.h
index 30808b1..27c5fe9 100644
--- a/include/nuttx/net/net.h
+++ b/include/nuttx/net/net.h
@@ -217,7 +217,7 @@ struct sock_intf_s
                     FAR socklen_t *fromlen);
 #ifdef CONFIG_NET_RECVMSG_CMSG
   CODE ssize_t    (*si_recvmsg)(FAR struct socket *psock,
-		            FAR struct msghdr *msg, int flags);
+                FAR struct msghdr *msg, int flags);
 #endif
   CODE int        (*si_close)(FAR struct socket *psock);
 #ifdef CONFIG_NET_USRSOCK


[incubator-nuttx] 11/31: Added CAN_RAW_FD_FRAMES sockopt support

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch SocketCAN
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 88d67a95741969b64516cf409688c1e2de236e49
Author: Peter van der Perk <pe...@nxp.com>
AuthorDate: Wed Feb 26 13:36:24 2020 +0100

    Added CAN_RAW_FD_FRAMES sockopt support
    
    Also CAN FD is disabled on startup, which is default behaviour for SocketCAN
---
 net/can/can.h            | 10 ++++++++++
 net/can/can_conn.c       |  3 +++
 net/can/can_getsockopt.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++
 net/can/can_recvfrom.c   | 28 +++++++++++++++++++++++----
 net/can/can_send.c       | 50 ++++++++++++++++++++++++++++++------------------
 net/can/can_setsockopt.c | 21 +++++++++++++++++---
 net/socket/getsockopt.c  |  4 ++--
 net/socket/setsockopt.c  |  6 ++++++
 8 files changed, 142 insertions(+), 28 deletions(-)

diff --git a/net/can/can.h b/net/can/can.h
index 67c8d6f..5992deb 100644
--- a/net/can/can.h
+++ b/net/can/can.h
@@ -104,6 +104,16 @@ struct can_conn_s
    */
 
   struct can_poll_s pollinfo[4]; /* FIXME make dynamic */
+  
+#ifdef CONFIG_NET_CANPROTO_OPTIONS
+  int32_t loopback;
+  int32_t recv_own_msgs;
+  int32_t fd_frames;
+  
+  /* TODO add filter support */
+#endif
+  
+  
 };
 
 /****************************************************************************
diff --git a/net/can/can_conn.c b/net/can/can_conn.c
index 4969f6d..21622b5 100644
--- a/net/can/can_conn.c
+++ b/net/can/can_conn.c
@@ -138,6 +138,9 @@ FAR struct can_conn_s *can_alloc(void)
       /* Make sure that the connection is marked as uninitialized */
 
       memset(conn, 0, sizeof(*conn));
+      
+      /* FIXME SocketCAN default behavior enables loopback */
+      
 
       /* Enqueue the connection into the active list */
 
diff --git a/net/can/can_getsockopt.c b/net/can/can_getsockopt.c
index 1fe8218..91720ad 100644
--- a/net/can/can_getsockopt.c
+++ b/net/can/can_getsockopt.c
@@ -114,12 +114,60 @@ int can_getsockopt(FAR struct socket *psock, int option,
         break;
 
       case CAN_RAW_LOOPBACK:
+        if (*value_len < sizeof(conn->loopback))
+          {
+            /* REVISIT: POSIX says that we should truncate the value if it
+             * is larger than value_len.   That just doesn't make sense
+             * to me in this case.
+             */
+
+            ret              = -EINVAL;
+          }
+        else
+          {
+            FAR int *loopback  = (FAR int32_t *)value;
+            *loopback          = conn->loopback;
+            *value_len         = sizeof(conn->loopback);
+            ret                = OK;
+          }
         break;
 
       case CAN_RAW_RECV_OWN_MSGS:
+        if (*value_len < sizeof(conn->recv_own_msgs))
+          {
+            /* REVISIT: POSIX says that we should truncate the value if it
+             * is larger than value_len.   That just doesn't make sense
+             * to me in this case.
+             */
+
+            ret              = -EINVAL;
+          }
+        else
+          {
+            FAR int *recv_own_msgs = (FAR int32_t *)value;
+            *recv_own_msgs         = conn->recv_own_msgs;
+            *value_len             = sizeof(conn->recv_own_msgs);
+            ret                    = OK;
+          }
         break;
 
       case CAN_RAW_FD_FRAMES:
+        if (*value_len < sizeof(conn->fd_frames))
+          {
+            /* REVISIT: POSIX says that we should truncate the value if it
+             * is larger than value_len.   That just doesn't make sense
+             * to me in this case.
+             */
+
+            ret              = -EINVAL;
+          }
+        else
+          {
+            FAR int *fd_frames = (FAR int32_t *)value;
+            *fd_frames         = conn->fd_frames;
+            *value_len         = sizeof(conn->fd_frames);
+            ret                = OK;
+          }
         break;
 
       case CAN_RAW_JOIN_FILTERS:
diff --git a/net/can/can_recvfrom.c b/net/can/can_recvfrom.c
index d2f71a6..f83d07c 100644
--- a/net/can/can_recvfrom.c
+++ b/net/can/can_recvfrom.c
@@ -276,6 +276,16 @@ static inline int can_readahead(struct can_recvfrom_s *pstate)
                              IOBUSER_NET_CAN_READAHEAD);
         }
 
+	  /* do not pass frames with DLC > 8 to a legacy socket */
+	  if (!conn->fd_frames)
+	    {
+		  struct canfd_frame *cfd = (struct canfd_frame *)pstate->pr_buffer;
+		  if (cfd->len > CAN_MAX_DLEN)
+		    {
+	  			return 0;
+		    }
+	    }
+
       return recvlen;
     }
 
@@ -287,6 +297,7 @@ static uint16_t can_recvfrom_eventhandler(FAR struct net_driver_s *dev,
                                           FAR void *pvpriv, uint16_t flags)
 {
   struct can_recvfrom_s *pstate = (struct can_recvfrom_s *)pvpriv;
+  struct can_conn_s *conn = (struct can_conn_s *)pstate->pr_sock->s_conn;
 
   /* 'priv' might be null in some race conditions (?) */
 
@@ -296,6 +307,18 @@ static uint16_t can_recvfrom_eventhandler(FAR struct net_driver_s *dev,
 
       if ((flags & CAN_NEWDATA) != 0)
         {
+    	  /* do not pass frames with DLC > 8 to a legacy socket */
+    	  if (!conn->fd_frames)
+    	    {
+    		  struct canfd_frame *cfd = (struct canfd_frame *)dev->d_appdata;
+    	      if (cfd->len > CAN_MAX_DLEN)
+    	      {
+    	    	/* DO WE NEED TO CLEAR FLAGS?? */
+    	        flags &= ~CAN_NEWDATA;
+  	  			return flags;
+    	      }
+    	    }
+
           /* Copy the packet */
 
           can_newdata(dev, pstate);
@@ -355,10 +378,7 @@ static ssize_t can_recvfrom_result(int result,
 
   if (pstate->pr_result < 0)
     {
-      /* This might return EAGAIN on a timeout or ENOTCONN on loss of
-       * connection (CAN only)
-       */
-
+      /* This might return EAGAIN on a timeout */
       return pstate->pr_result;
     }
 
diff --git a/net/can/can_send.c b/net/can/can_send.c
index 6b7a609..1d8677d 100644
--- a/net/can/can_send.c
+++ b/net/can/can_send.c
@@ -184,6 +184,21 @@ ssize_t psock_can_send(FAR struct socket *psock, FAR const void *buf,
     {
       return -ENODEV;
     }
+    
+  if(conn->fd_frames)
+    {
+        if(len != CANFD_MTU && len != CAN_MTU)
+          {
+              return -EINVAL;
+          } 
+    }
+    else 
+    {
+        if(len != CAN_MTU)
+          {
+              return -EINVAL;
+          }
+    }
 
   /* Perform the send operation */
 
@@ -205,33 +220,30 @@ ssize_t psock_can_send(FAR struct socket *psock, FAR const void *buf,
   state.snd_buflen    = len;            /* Number of bytes to send */
   state.snd_buffer    = buf;            /* Buffer to send from */
 
-  if (len > 0)
-    {
-      /* Allocate resource to receive a callback */
+  /* Allocate resource to receive a callback */
 
-      state.snd_cb = can_callback_alloc(dev, conn);
-      if (state.snd_cb)
-        {
-          /* Set up the callback in the connection */
+  state.snd_cb = can_callback_alloc(dev, conn);
+  if (state.snd_cb)
+    {
+      /* Set up the callback in the connection */
 
-          state.snd_cb->flags = CAN_POLL;
-          state.snd_cb->priv  = (FAR void *)&state;
-          state.snd_cb->event = psock_send_eventhandler;
+      state.snd_cb->flags = CAN_POLL;
+      state.snd_cb->priv  = (FAR void *)&state;
+      state.snd_cb->event = psock_send_eventhandler;
 
-          /* Notify the device driver that new TX data is available. */
+      /* Notify the device driver that new TX data is available. */
 
-          netdev_txnotify_dev(dev);
+      netdev_txnotify_dev(dev);
 
-          /* Wait for the send to complete or an error to occur.
-           * net_lockedwait will also terminate if a signal is received.
-           */
+      /* Wait for the send to complete or an error to occur.
+      * net_lockedwait will also terminate if a signal is received.
+      */
 
-          ret = net_lockedwait(&state.snd_sem);
+      ret = net_lockedwait(&state.snd_sem);
 
-          /* Make sure that no further events are processed */
+      /* Make sure that no further events are processed */
 
-          can_callback_free(dev, conn, state.snd_cb);
-        }
+      can_callback_free(dev, conn, state.snd_cb);
     }
 
   nxsem_destroy(&state.snd_sem);
diff --git a/net/can/can_setsockopt.c b/net/can/can_setsockopt.c
index 2d117a8..3bad6e0 100644
--- a/net/can/can_setsockopt.c
+++ b/net/can/can_setsockopt.c
@@ -108,13 +108,28 @@ int can_setsockopt(FAR struct socket *psock, int option,
         break;
 
       case CAN_RAW_LOOPBACK:
-        break;
+		if (value_len != sizeof(conn->loopback))
+			return -EINVAL;
+
+		conn->loopback = *(FAR int32_t *)value;
+
+		break;
 
       case CAN_RAW_RECV_OWN_MSGS:
-        break;
+		if (value_len != sizeof(conn->recv_own_msgs))
+			return -EINVAL;
+
+		conn->recv_own_msgs = *(FAR int32_t *)value;
+
+		break;
 
       case CAN_RAW_FD_FRAMES:
-        break;
+		if (value_len != sizeof(conn->fd_frames))
+			return -EINVAL;
+
+		conn->fd_frames = *(FAR int32_t *)value;
+
+		break;
 
       case CAN_RAW_JOIN_FILTERS:
         break;
diff --git a/net/socket/getsockopt.c b/net/socket/getsockopt.c
index 6d71106..fa58e6d 100644
--- a/net/socket/getsockopt.c
+++ b/net/socket/getsockopt.c
@@ -371,8 +371,8 @@ int psock_getsockopt(FAR struct socket *psock, int level, int option,
        break;
 #endif
 
-      case SOL_CAN_RAW:
-#ifdef CONFIG_NET_TCPPROTO_OPTIONS
+      case SOL_CAN_RAW:/* CAN protocol socket options (see include/netpacket/can.h) */
+#ifdef CONFIG_NET_CANPROTO_OPTIONS
        ret = can_getsockopt(psock, option, value, value_len);
 #endif
        break;
diff --git a/net/socket/setsockopt.c b/net/socket/setsockopt.c
index 211a1df..46e1b6e 100644
--- a/net/socket/setsockopt.c
+++ b/net/socket/setsockopt.c
@@ -399,6 +399,12 @@ int psock_setsockopt(FAR struct socket *psock, int level, int option,
         break;
 #endif
 
+#ifdef CONFIG_NET_CAN
+      case SOL_CAN_RAW:   /* CAN protocol socket options (see include/netpacket/can.h) */
+        ret = can_setsockopt(psock, option, value, value_len);
+        break;
+#endif
+
       default:         /* The provided level is invalid */
         ret = -EINVAL;
         break;


[incubator-nuttx] 20/31: S32K1XX Added High res timer support FlexCAN allocate memory for timestamp

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch SocketCAN
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 962049c797e8407627857b288776819d28896cf8
Author: Peter van der Perk <pe...@nxp.com>
AuthorDate: Thu Mar 12 13:59:33 2020 +0100

    S32K1XX Added High res timer support
    FlexCAN allocate memory for timestamp
---
 arch/arm/src/s32k1xx/s32k1xx_flexcan.c | 14 +++++-
 arch/arm/src/s32k1xx/s32k1xx_rtc.c     | 79 ++++++++++++++++++++++++++++++++--
 arch/arm/src/s32k1xx/s32k1xx_rtc.h     |  8 ----
 3 files changed, 87 insertions(+), 14 deletions(-)

diff --git a/arch/arm/src/s32k1xx/s32k1xx_flexcan.c b/arch/arm/src/s32k1xx/s32k1xx_flexcan.c
index 8e79833..2654c2e 100644
--- a/arch/arm/src/s32k1xx/s32k1xx_flexcan.c
+++ b/arch/arm/src/s32k1xx/s32k1xx_flexcan.c
@@ -49,6 +49,10 @@
 #include "s32k1xx_pin.h"
 #include "s32k1xx_flexcan.h"
 
+#ifdef CONFIG_NET_TIMESTAMP
+#include <sys/time.h>
+#endif
+
 #ifdef CONFIG_S32K1XX_FLEXCAN
 
 /****************************************************************************
@@ -108,6 +112,12 @@
 
 #define POOL_SIZE                   1
 
+#ifdef CONFIG_NET_TIMESTAMP
+#define MSG_DATA                    sizeof(struct timeval)
+#else
+#define MSG_DATA                    0
+#endif
+
 /* Interrupt flags for RX fifo */
 #define IFLAG1_RXFIFO               (CAN_FIFO_NE | CAN_FIFO_WARN | CAN_FIFO_OV)
 
@@ -223,8 +233,8 @@ struct s32k1xx_driver_s
 static struct s32k1xx_driver_s g_flexcan[CONFIG_S32K1XX_ENET_NETHIFS];
 
 #ifdef CAN_FD
-static uint8_t g_tx_pool[sizeof(struct canfd_frame)*POOL_SIZE];
-static uint8_t g_rx_pool[sizeof(struct canfd_frame)*POOL_SIZE];
+static uint8_t g_tx_pool[(sizeof(struct canfd_frame)+MSG_DATA)*POOL_SIZE];
+static uint8_t g_rx_pool[(sizeof(struct canfd_frame)+MSG_DATA)*POOL_SIZE];
 #else
 static uint8_t g_tx_pool[sizeof(struct can_frame)*POOL_SIZE]
                __attribute__((aligned(ARMV7M_DCACHE_LINESIZE)));
diff --git a/arch/arm/src/s32k1xx/s32k1xx_rtc.c b/arch/arm/src/s32k1xx/s32k1xx_rtc.c
index 7c70b76..7f84dcf 100644
--- a/arch/arm/src/s32k1xx/s32k1xx_rtc.c
+++ b/arch/arm/src/s32k1xx/s32k1xx_rtc.c
@@ -157,11 +157,11 @@ int up_rtc_initialize(void)
 
   putreg32(regval, S32K1XX_RTC_CR);
 
-  /* Set LPO_1KHZ clock source */
+  /* Increment on 32.768Khz clock */
 
   regval  = getreg32(S32K1XX_RTC_CR);
 
-  regval |= RTC_CR_LPOS;
+  regval &= ~RTC_CR_LPOS;
 
   putreg32(regval, S32K1XX_RTC_CR);
 
@@ -181,6 +181,16 @@ int up_rtc_initialize(void)
 
   putreg32(regval, S32K1XX_RTC_CR);
 
+  regval  = getreg32(S32K1XX_RTC_SR);
+
+  if(regval & RTC_SR_TIF)
+    {
+	  regval &= ~RTC_SR_TCE;
+	  putreg32(regval, S32K1XX_RTC_SR);
+      /* Write TSR register to clear invalid */
+	  putreg32(0x0, S32K1XX_RTC_TSR);
+    }
+
   /* Enable the rtc */
 
   s32k1xx_rtc_enable();
@@ -207,7 +217,7 @@ int up_rtc_initialize(void)
  *   The current time in seconds
  *
  ****************************************************************************/
-
+#ifndef CONFIG_RTC_HIRES
 time_t up_rtc_time(void)
 {
   uint32_t regval;
@@ -217,6 +227,55 @@ time_t up_rtc_time(void)
 
   return (uint32_t) (regval);
 }
+#endif
+
+/****************************************************************************
+ * Name: up_rtc_gettime
+ *
+ * Description:
+ *   Get the current time from the high resolution RTC clock/counter.  This
+ *   interface is only supported by the high-resolution RTC/counter hardware
+ *   implementation. It is used to replace the system timer.
+ *
+ * Input Parameters:
+ *   tp - The location to return the high resolution time value.
+ *
+ * Returned Value:
+ *   Zero (OK) on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_RTC_HIRES
+int up_rtc_gettime(FAR struct timespec *tp)
+{
+  irqstate_t flags;
+  uint32_t seconds;
+  uint32_t prescaler;
+  uint32_t prescaler2;
+
+  /* Get prescaler and seconds register. this is in a loop which ensures that
+   * registers will be re-read if during the reads the prescaler has
+   * wrapped-around.
+   */
+
+  flags = enter_critical_section();
+  do
+    {
+      prescaler = getreg32(S32K1XX_RTC_TPR);
+      seconds = getreg32(S32K1XX_RTC_TSR);
+      prescaler2 = getreg32(S32K1XX_RTC_TPR);
+    }
+  while (prescaler > prescaler2);
+
+  leave_critical_section(flags);
+
+  /* Build seconds + nanoseconds from seconds and prescaler register */
+
+  tp->tv_sec = seconds;
+  tp->tv_nsec = prescaler * (1000000000 / CONFIG_RTC_FREQUENCY);
+  return OK;
+}
+#endif
 
 /****************************************************************************
  * Name: up_rtc_settime
@@ -236,13 +295,25 @@ time_t up_rtc_time(void)
 int up_rtc_settime(FAR const struct timespec *ts)
 {
   DEBUGASSERT(ts != NULL);
+  
+  irqstate_t flags;
+  uint32_t seconds;
+  uint32_t prescaler;
+  
+  seconds = ts->tv_sec;
+  prescaler = ts->tv_nsec * (CONFIG_RTC_FREQUENCY / 1000000000);
+
+  flags = enter_critical_section();
 
   s32k1xx_rtc_disable();
 
-  putreg32((uint32_t)ts->tv_sec, S32K1XX_RTC_TSR);
+  putreg32(prescaler, S32K1XX_RTC_TPR); /* Always write prescaler first */
+  putreg32(seconds, S32K1XX_RTC_TSR);
 
   s32k1xx_rtc_enable();
 
+  leave_critical_section(flags);
+
   return OK;
 }
 
diff --git a/arch/arm/src/s32k1xx/s32k1xx_rtc.h b/arch/arm/src/s32k1xx/s32k1xx_rtc.h
index b00c3d3..35ce10d 100644
--- a/arch/arm/src/s32k1xx/s32k1xx_rtc.h
+++ b/arch/arm/src/s32k1xx/s32k1xx_rtc.h
@@ -58,14 +58,6 @@
 #    error CONFIG_RTC_PERIODIC should not be selected with this driver
 #  endif
 
-/* REVISIT: This is probably supportable.  The 47 bit timer does have
- * accuracy greater than 1 second.
- */
-
-#  ifdef CONFIG_RTC_HIRES
-#    error CONFIG_RTC_PERIODIC should not be selected with this driver
-#  endif
-
 /****************************************************************************
  * Public Function Prototypes
  ****************************************************************************/