cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ca8210.c (84454B)


      1/*
      2 * http://www.cascoda.com/products/ca-821x/
      3 * Copyright (c) 2016, Cascoda, Ltd.
      4 * All rights reserved.
      5 *
      6 * This code is dual-licensed under both GPLv2 and 3-clause BSD. What follows is
      7 * the license notice for both respectively.
      8 *
      9 *******************************************************************************
     10 *
     11 * This program is free software; you can redistribute it and/or
     12 * modify it under the terms of the GNU General Public License
     13 * as published by the Free Software Foundation; either version 2
     14 * of the License, or (at your option) any later version.
     15 *
     16 * This program is distributed in the hope that it will be useful,
     17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     19 * GNU General Public License for more details.
     20 *
     21 *******************************************************************************
     22 *
     23 * Redistribution and use in source and binary forms, with or without
     24 * modification, are permitted provided that the following conditions are met:
     25 *
     26 * 1. Redistributions of source code must retain the above copyright notice,
     27 * this list of conditions and the following disclaimer.
     28 *
     29 * 2. Redistributions in binary form must reproduce the above copyright notice,
     30 * this list of conditions and the following disclaimer in the documentation
     31 * and/or other materials provided with the distribution.
     32 *
     33 * 3. Neither the name of the copyright holder nor the names of its contributors
     34 * may be used to endorse or promote products derived from this software without
     35 * specific prior written permission.
     36 *
     37 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     38 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     39 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     40 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
     41 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     42 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     43 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     44 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     45 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     47 * POSSIBILITY OF SUCH DAMAGE.
     48 */
     49
     50#include <linux/cdev.h>
     51#include <linux/clk-provider.h>
     52#include <linux/debugfs.h>
     53#include <linux/delay.h>
     54#include <linux/gpio.h>
     55#include <linux/ieee802154.h>
     56#include <linux/io.h>
     57#include <linux/kfifo.h>
     58#include <linux/of.h>
     59#include <linux/of_device.h>
     60#include <linux/of_gpio.h>
     61#include <linux/module.h>
     62#include <linux/mutex.h>
     63#include <linux/poll.h>
     64#include <linux/skbuff.h>
     65#include <linux/slab.h>
     66#include <linux/spi/spi.h>
     67#include <linux/spinlock.h>
     68#include <linux/string.h>
     69#include <linux/workqueue.h>
     70#include <linux/interrupt.h>
     71
     72#include <net/ieee802154_netdev.h>
     73#include <net/mac802154.h>
     74
     75#define DRIVER_NAME "ca8210"
     76
     77/* external clock frequencies */
     78#define ONE_MHZ      1000000
     79#define TWO_MHZ      (2 * ONE_MHZ)
     80#define FOUR_MHZ     (4 * ONE_MHZ)
     81#define EIGHT_MHZ    (8 * ONE_MHZ)
     82#define SIXTEEN_MHZ  (16 * ONE_MHZ)
     83
     84/* spi constants */
     85#define CA8210_SPI_BUF_SIZE 256
     86#define CA8210_SYNC_TIMEOUT 1000     /* Timeout for synchronous commands [ms] */
     87
     88/* test interface constants */
     89#define CA8210_TEST_INT_FILE_NAME "ca8210_test"
     90#define CA8210_TEST_INT_FIFO_SIZE 256
     91
     92/* HWME attribute IDs */
     93#define HWME_EDTHRESHOLD       (0x04)
     94#define HWME_EDVALUE           (0x06)
     95#define HWME_SYSCLKOUT         (0x0F)
     96#define HWME_LQILIMIT          (0x11)
     97
     98/* TDME attribute IDs */
     99#define TDME_CHANNEL          (0x00)
    100#define TDME_ATM_CONFIG       (0x06)
    101
    102#define MAX_HWME_ATTRIBUTE_SIZE  16
    103#define MAX_TDME_ATTRIBUTE_SIZE  2
    104
    105/* PHY/MAC PIB Attribute Enumerations */
    106#define PHY_CURRENT_CHANNEL               (0x00)
    107#define PHY_TRANSMIT_POWER                (0x02)
    108#define PHY_CCA_MODE                      (0x03)
    109#define MAC_ASSOCIATION_PERMIT            (0x41)
    110#define MAC_AUTO_REQUEST                  (0x42)
    111#define MAC_BATT_LIFE_EXT                 (0x43)
    112#define MAC_BATT_LIFE_EXT_PERIODS         (0x44)
    113#define MAC_BEACON_PAYLOAD                (0x45)
    114#define MAC_BEACON_PAYLOAD_LENGTH         (0x46)
    115#define MAC_BEACON_ORDER                  (0x47)
    116#define MAC_GTS_PERMIT                    (0x4d)
    117#define MAC_MAX_CSMA_BACKOFFS             (0x4e)
    118#define MAC_MIN_BE                        (0x4f)
    119#define MAC_PAN_ID                        (0x50)
    120#define MAC_PROMISCUOUS_MODE              (0x51)
    121#define MAC_RX_ON_WHEN_IDLE               (0x52)
    122#define MAC_SHORT_ADDRESS                 (0x53)
    123#define MAC_SUPERFRAME_ORDER              (0x54)
    124#define MAC_ASSOCIATED_PAN_COORD          (0x56)
    125#define MAC_MAX_BE                        (0x57)
    126#define MAC_MAX_FRAME_RETRIES             (0x59)
    127#define MAC_RESPONSE_WAIT_TIME            (0x5A)
    128#define MAC_SECURITY_ENABLED              (0x5D)
    129
    130#define MAC_AUTO_REQUEST_SECURITY_LEVEL   (0x78)
    131#define MAC_AUTO_REQUEST_KEY_ID_MODE      (0x79)
    132
    133#define NS_IEEE_ADDRESS                   (0xFF) /* Non-standard IEEE address */
    134
    135/* MAC Address Mode Definitions */
    136#define MAC_MODE_NO_ADDR                (0x00)
    137#define MAC_MODE_SHORT_ADDR             (0x02)
    138#define MAC_MODE_LONG_ADDR              (0x03)
    139
    140/* MAC constants */
    141#define MAX_BEACON_OVERHEAD        (75)
    142#define MAX_BEACON_PAYLOAD_LENGTH  (IEEE802154_MTU - MAX_BEACON_OVERHEAD)
    143
    144#define MAX_ATTRIBUTE_SIZE              (122)
    145#define MAX_DATA_SIZE                   (114)
    146
    147#define CA8210_VALID_CHANNELS                 (0x07FFF800)
    148
    149/* MAC workarounds for V1.1 and MPW silicon (V0.x) */
    150#define CA8210_MAC_WORKAROUNDS (0)
    151#define CA8210_MAC_MPW         (0)
    152
    153/* memory manipulation macros */
    154#define LS_BYTE(x)     ((u8)((x) & 0xFF))
    155#define MS_BYTE(x)     ((u8)(((x) >> 8) & 0xFF))
    156
    157/* message ID codes in SPI commands */
    158/* downstream */
    159#define MCPS_DATA_REQUEST                     (0x00)
    160#define MLME_ASSOCIATE_REQUEST                (0x02)
    161#define MLME_ASSOCIATE_RESPONSE               (0x03)
    162#define MLME_DISASSOCIATE_REQUEST             (0x04)
    163#define MLME_GET_REQUEST                      (0x05)
    164#define MLME_ORPHAN_RESPONSE                  (0x06)
    165#define MLME_RESET_REQUEST                    (0x07)
    166#define MLME_RX_ENABLE_REQUEST                (0x08)
    167#define MLME_SCAN_REQUEST                     (0x09)
    168#define MLME_SET_REQUEST                      (0x0A)
    169#define MLME_START_REQUEST                    (0x0B)
    170#define MLME_POLL_REQUEST                     (0x0D)
    171#define HWME_SET_REQUEST                      (0x0E)
    172#define HWME_GET_REQUEST                      (0x0F)
    173#define TDME_SETSFR_REQUEST                   (0x11)
    174#define TDME_GETSFR_REQUEST                   (0x12)
    175#define TDME_SET_REQUEST                      (0x14)
    176/* upstream */
    177#define MCPS_DATA_INDICATION                  (0x00)
    178#define MCPS_DATA_CONFIRM                     (0x01)
    179#define MLME_RESET_CONFIRM                    (0x0A)
    180#define MLME_SET_CONFIRM                      (0x0E)
    181#define MLME_START_CONFIRM                    (0x0F)
    182#define HWME_SET_CONFIRM                      (0x12)
    183#define HWME_GET_CONFIRM                      (0x13)
    184#define HWME_WAKEUP_INDICATION		      (0x15)
    185#define TDME_SETSFR_CONFIRM                   (0x17)
    186
    187/* SPI command IDs */
    188/* bit indicating a confirm or indication from slave to master */
    189#define SPI_S2M                            (0x20)
    190/* bit indicating a synchronous message */
    191#define SPI_SYN                            (0x40)
    192
    193/* SPI command definitions */
    194#define SPI_IDLE                           (0xFF)
    195#define SPI_NACK                           (0xF0)
    196
    197#define SPI_MCPS_DATA_REQUEST          (MCPS_DATA_REQUEST)
    198#define SPI_MCPS_DATA_INDICATION       (MCPS_DATA_INDICATION + SPI_S2M)
    199#define SPI_MCPS_DATA_CONFIRM          (MCPS_DATA_CONFIRM + SPI_S2M)
    200
    201#define SPI_MLME_ASSOCIATE_REQUEST     (MLME_ASSOCIATE_REQUEST)
    202#define SPI_MLME_RESET_REQUEST         (MLME_RESET_REQUEST + SPI_SYN)
    203#define SPI_MLME_SET_REQUEST           (MLME_SET_REQUEST + SPI_SYN)
    204#define SPI_MLME_START_REQUEST         (MLME_START_REQUEST + SPI_SYN)
    205#define SPI_MLME_RESET_CONFIRM         (MLME_RESET_CONFIRM + SPI_S2M + SPI_SYN)
    206#define SPI_MLME_SET_CONFIRM           (MLME_SET_CONFIRM + SPI_S2M + SPI_SYN)
    207#define SPI_MLME_START_CONFIRM         (MLME_START_CONFIRM + SPI_S2M + SPI_SYN)
    208
    209#define SPI_HWME_SET_REQUEST           (HWME_SET_REQUEST + SPI_SYN)
    210#define SPI_HWME_GET_REQUEST           (HWME_GET_REQUEST + SPI_SYN)
    211#define SPI_HWME_SET_CONFIRM           (HWME_SET_CONFIRM + SPI_S2M + SPI_SYN)
    212#define SPI_HWME_GET_CONFIRM           (HWME_GET_CONFIRM + SPI_S2M + SPI_SYN)
    213#define SPI_HWME_WAKEUP_INDICATION     (HWME_WAKEUP_INDICATION + SPI_S2M)
    214
    215#define SPI_TDME_SETSFR_REQUEST        (TDME_SETSFR_REQUEST + SPI_SYN)
    216#define SPI_TDME_SET_REQUEST           (TDME_SET_REQUEST + SPI_SYN)
    217#define SPI_TDME_SETSFR_CONFIRM        (TDME_SETSFR_CONFIRM + SPI_S2M + SPI_SYN)
    218
    219/* TDME SFR addresses */
    220/* Page 0 */
    221#define CA8210_SFR_PACFG                   (0xB1)
    222#define CA8210_SFR_MACCON                  (0xD8)
    223#define CA8210_SFR_PACFGIB                 (0xFE)
    224/* Page 1 */
    225#define CA8210_SFR_LOTXCAL                 (0xBF)
    226#define CA8210_SFR_PTHRH                   (0xD1)
    227#define CA8210_SFR_PRECFG                  (0xD3)
    228#define CA8210_SFR_LNAGX40                 (0xE1)
    229#define CA8210_SFR_LNAGX41                 (0xE2)
    230#define CA8210_SFR_LNAGX42                 (0xE3)
    231#define CA8210_SFR_LNAGX43                 (0xE4)
    232#define CA8210_SFR_LNAGX44                 (0xE5)
    233#define CA8210_SFR_LNAGX45                 (0xE6)
    234#define CA8210_SFR_LNAGX46                 (0xE7)
    235#define CA8210_SFR_LNAGX47                 (0xE9)
    236
    237#define PACFGIB_DEFAULT_CURRENT            (0x3F)
    238#define PTHRH_DEFAULT_THRESHOLD            (0x5A)
    239#define LNAGX40_DEFAULT_GAIN               (0x29) /* 10dB */
    240#define LNAGX41_DEFAULT_GAIN               (0x54) /* 21dB */
    241#define LNAGX42_DEFAULT_GAIN               (0x6C) /* 27dB */
    242#define LNAGX43_DEFAULT_GAIN               (0x7A) /* 30dB */
    243#define LNAGX44_DEFAULT_GAIN               (0x84) /* 33dB */
    244#define LNAGX45_DEFAULT_GAIN               (0x8B) /* 34dB */
    245#define LNAGX46_DEFAULT_GAIN               (0x92) /* 36dB */
    246#define LNAGX47_DEFAULT_GAIN               (0x96) /* 37dB */
    247
    248#define CA8210_IOCTL_HARD_RESET            (0x00)
    249
    250/* Structs/Enums */
    251
    252/**
    253 * struct cas_control - spi transfer structure
    254 * @msg:                  spi_message for each exchange
    255 * @transfer:             spi_transfer for each exchange
    256 * @tx_buf:               source array for transmission
    257 * @tx_in_buf:            array storing bytes received during transmission
    258 * @priv:                 pointer to private data
    259 *
    260 * This structure stores all the necessary data passed around during a single
    261 * spi exchange.
    262 */
    263struct cas_control {
    264	struct spi_message msg;
    265	struct spi_transfer transfer;
    266
    267	u8 tx_buf[CA8210_SPI_BUF_SIZE];
    268	u8 tx_in_buf[CA8210_SPI_BUF_SIZE];
    269
    270	struct ca8210_priv *priv;
    271};
    272
    273/**
    274 * struct ca8210_test - ca8210 test interface structure
    275 * @ca8210_dfs_spi_int: pointer to the entry in the debug fs for this device
    276 * @up_fifo:            fifo for upstream messages
    277 * @readq:              read wait queue
    278 *
    279 * This structure stores all the data pertaining to the debug interface
    280 */
    281struct ca8210_test {
    282	struct dentry *ca8210_dfs_spi_int;
    283	struct kfifo up_fifo;
    284	wait_queue_head_t readq;
    285};
    286
    287/**
    288 * struct ca8210_priv - ca8210 private data structure
    289 * @spi:                    pointer to the ca8210 spi device object
    290 * @hw:                     pointer to the ca8210 ieee802154_hw object
    291 * @hw_registered:          true if hw has been registered with ieee802154
    292 * @lock:                   spinlock protecting the private data area
    293 * @mlme_workqueue:           workqueue for triggering MLME Reset
    294 * @irq_workqueue:          workqueue for irq processing
    295 * @tx_skb:                 current socket buffer to transmit
    296 * @nextmsduhandle:         msdu handle to pass to the 15.4 MAC layer for the
    297 *                           next transmission
    298 * @clk:                    external clock provided by the ca8210
    299 * @last_dsn:               sequence number of last data packet received, for
    300 *                           resend detection
    301 * @test:                   test interface data section for this instance
    302 * @async_tx_pending:       true if an asynchronous transmission was started and
    303 *                           is not complete
    304 * @sync_command_response:  pointer to buffer to fill with sync response
    305 * @ca8210_is_awake:        nonzero if ca8210 is initialised, ready for comms
    306 * @sync_down:              counts number of downstream synchronous commands
    307 * @sync_up:                counts number of upstream synchronous commands
    308 * @spi_transfer_complete:  completion object for a single spi_transfer
    309 * @sync_exchange_complete: completion object for a complete synchronous API
    310 *                          exchange
    311 * @promiscuous:            whether the ca8210 is in promiscuous mode or not
    312 * @retries:                records how many times the current pending spi
    313 *                          transfer has been retried
    314 */
    315struct ca8210_priv {
    316	struct spi_device *spi;
    317	struct ieee802154_hw *hw;
    318	bool hw_registered;
    319	spinlock_t lock;
    320	struct workqueue_struct *mlme_workqueue;
    321	struct workqueue_struct *irq_workqueue;
    322	struct sk_buff *tx_skb;
    323	u8 nextmsduhandle;
    324	struct clk *clk;
    325	int last_dsn;
    326	struct ca8210_test test;
    327	bool async_tx_pending;
    328	u8 *sync_command_response;
    329	struct completion ca8210_is_awake;
    330	int sync_down, sync_up;
    331	struct completion spi_transfer_complete, sync_exchange_complete;
    332	bool promiscuous;
    333	int retries;
    334};
    335
    336/**
    337 * struct work_priv_container - link between a work object and the relevant
    338 *                              device's private data
    339 * @work: work object being executed
    340 * @priv: device's private data section
    341 *
    342 */
    343struct work_priv_container {
    344	struct work_struct work;
    345	struct ca8210_priv *priv;
    346};
    347
    348/**
    349 * struct ca8210_platform_data - ca8210 platform data structure
    350 * @extclockenable: true if the external clock is to be enabled
    351 * @extclockfreq:   frequency of the external clock
    352 * @extclockgpio:   ca8210 output gpio of the external clock
    353 * @gpio_reset:     gpio number of ca8210 reset line
    354 * @gpio_irq:       gpio number of ca8210 interrupt line
    355 * @irq_id:         identifier for the ca8210 irq
    356 *
    357 */
    358struct ca8210_platform_data {
    359	bool extclockenable;
    360	unsigned int extclockfreq;
    361	unsigned int extclockgpio;
    362	int gpio_reset;
    363	int gpio_irq;
    364	int irq_id;
    365};
    366
    367/**
    368 * struct fulladdr - full MAC addressing information structure
    369 * @mode:    address mode (none, short, extended)
    370 * @pan_id:  16-bit LE pan id
    371 * @address: LE address, variable length as specified by mode
    372 *
    373 */
    374struct fulladdr {
    375	u8         mode;
    376	u8         pan_id[2];
    377	u8         address[8];
    378};
    379
    380/**
    381 * union macaddr: generic MAC address container
    382 * @short_address: 16-bit short address
    383 * @ieee_address:  64-bit extended address as LE byte array
    384 *
    385 */
    386union macaddr {
    387	u16        short_address;
    388	u8         ieee_address[8];
    389};
    390
    391/**
    392 * struct secspec: security specification for SAP commands
    393 * @security_level: 0-7, controls level of authentication & encryption
    394 * @key_id_mode:    0-3, specifies how to obtain key
    395 * @key_source:     extended key retrieval data
    396 * @key_index:      single-byte key identifier
    397 *
    398 */
    399struct secspec {
    400	u8         security_level;
    401	u8         key_id_mode;
    402	u8         key_source[8];
    403	u8         key_index;
    404};
    405
    406/* downlink functions parameter set definitions */
    407struct mcps_data_request_pset {
    408	u8              src_addr_mode;
    409	struct fulladdr dst;
    410	u8              msdu_length;
    411	u8              msdu_handle;
    412	u8              tx_options;
    413	u8              msdu[MAX_DATA_SIZE];
    414};
    415
    416struct mlme_set_request_pset {
    417	u8         pib_attribute;
    418	u8         pib_attribute_index;
    419	u8         pib_attribute_length;
    420	u8         pib_attribute_value[MAX_ATTRIBUTE_SIZE];
    421};
    422
    423struct hwme_set_request_pset {
    424	u8         hw_attribute;
    425	u8         hw_attribute_length;
    426	u8         hw_attribute_value[MAX_HWME_ATTRIBUTE_SIZE];
    427};
    428
    429struct hwme_get_request_pset {
    430	u8         hw_attribute;
    431};
    432
    433struct tdme_setsfr_request_pset {
    434	u8         sfr_page;
    435	u8         sfr_address;
    436	u8         sfr_value;
    437};
    438
    439/* uplink functions parameter set definitions */
    440struct hwme_set_confirm_pset {
    441	u8         status;
    442	u8         hw_attribute;
    443};
    444
    445struct hwme_get_confirm_pset {
    446	u8         status;
    447	u8         hw_attribute;
    448	u8         hw_attribute_length;
    449	u8         hw_attribute_value[MAX_HWME_ATTRIBUTE_SIZE];
    450};
    451
    452struct tdme_setsfr_confirm_pset {
    453	u8         status;
    454	u8         sfr_page;
    455	u8         sfr_address;
    456};
    457
    458struct mac_message {
    459	u8      command_id;
    460	u8      length;
    461	union {
    462		struct mcps_data_request_pset       data_req;
    463		struct mlme_set_request_pset        set_req;
    464		struct hwme_set_request_pset        hwme_set_req;
    465		struct hwme_get_request_pset        hwme_get_req;
    466		struct tdme_setsfr_request_pset     tdme_set_sfr_req;
    467		struct hwme_set_confirm_pset        hwme_set_cnf;
    468		struct hwme_get_confirm_pset        hwme_get_cnf;
    469		struct tdme_setsfr_confirm_pset     tdme_set_sfr_cnf;
    470		u8                                  u8param;
    471		u8                                  status;
    472		u8                                  payload[148];
    473	} pdata;
    474};
    475
    476union pa_cfg_sfr {
    477	struct {
    478		u8 bias_current_trim     : 3;
    479		u8 /* reserved */        : 1;
    480		u8 buffer_capacitor_trim : 3;
    481		u8 boost                 : 1;
    482	};
    483	u8 paib;
    484};
    485
    486struct preamble_cfg_sfr {
    487	u8 timeout_symbols      : 3;
    488	u8 acquisition_symbols  : 3;
    489	u8 search_symbols       : 2;
    490};
    491
    492static int (*cascoda_api_upstream)(
    493	const u8 *buf,
    494	size_t len,
    495	void *device_ref
    496);
    497
    498/**
    499 * link_to_linux_err() - Translates an 802.15.4 return code into the closest
    500 *                       linux error
    501 * @link_status:  802.15.4 status code
    502 *
    503 * Return: 0 or Linux error code
    504 */
    505static int link_to_linux_err(int link_status)
    506{
    507	if (link_status < 0) {
    508		/* status is already a Linux code */
    509		return link_status;
    510	}
    511	switch (link_status) {
    512	case IEEE802154_SUCCESS:
    513	case IEEE802154_REALIGNMENT:
    514		return 0;
    515	case IEEE802154_IMPROPER_KEY_TYPE:
    516		return -EKEYREJECTED;
    517	case IEEE802154_IMPROPER_SECURITY_LEVEL:
    518	case IEEE802154_UNSUPPORTED_LEGACY:
    519	case IEEE802154_DENIED:
    520		return -EACCES;
    521	case IEEE802154_BEACON_LOST:
    522	case IEEE802154_NO_ACK:
    523	case IEEE802154_NO_BEACON:
    524		return -ENETUNREACH;
    525	case IEEE802154_CHANNEL_ACCESS_FAILURE:
    526	case IEEE802154_TX_ACTIVE:
    527	case IEEE802154_SCAN_IN_PROGRESS:
    528		return -EBUSY;
    529	case IEEE802154_DISABLE_TRX_FAILURE:
    530	case IEEE802154_OUT_OF_CAP:
    531		return -EAGAIN;
    532	case IEEE802154_FRAME_TOO_LONG:
    533		return -EMSGSIZE;
    534	case IEEE802154_INVALID_GTS:
    535	case IEEE802154_PAST_TIME:
    536		return -EBADSLT;
    537	case IEEE802154_INVALID_HANDLE:
    538		return -EBADMSG;
    539	case IEEE802154_INVALID_PARAMETER:
    540	case IEEE802154_UNSUPPORTED_ATTRIBUTE:
    541	case IEEE802154_ON_TIME_TOO_LONG:
    542	case IEEE802154_INVALID_INDEX:
    543		return -EINVAL;
    544	case IEEE802154_NO_DATA:
    545		return -ENODATA;
    546	case IEEE802154_NO_SHORT_ADDRESS:
    547		return -EFAULT;
    548	case IEEE802154_PAN_ID_CONFLICT:
    549		return -EADDRINUSE;
    550	case IEEE802154_TRANSACTION_EXPIRED:
    551		return -ETIME;
    552	case IEEE802154_TRANSACTION_OVERFLOW:
    553		return -ENOBUFS;
    554	case IEEE802154_UNAVAILABLE_KEY:
    555		return -ENOKEY;
    556	case IEEE802154_INVALID_ADDRESS:
    557		return -ENXIO;
    558	case IEEE802154_TRACKING_OFF:
    559	case IEEE802154_SUPERFRAME_OVERLAP:
    560		return -EREMOTEIO;
    561	case IEEE802154_LIMIT_REACHED:
    562		return -EDQUOT;
    563	case IEEE802154_READ_ONLY:
    564		return -EROFS;
    565	default:
    566		return -EPROTO;
    567	}
    568}
    569
    570/**
    571 * ca8210_test_int_driver_write() - Writes a message to the test interface to be
    572 *                                  read by the userspace
    573 * @buf:  Buffer containing upstream message
    574 * @len:  length of message to write
    575 * @spi:  SPI device of message originator
    576 *
    577 * Return: 0 or linux error code
    578 */
    579static int ca8210_test_int_driver_write(
    580	const u8       *buf,
    581	size_t          len,
    582	void           *spi
    583)
    584{
    585	struct ca8210_priv *priv = spi_get_drvdata(spi);
    586	struct ca8210_test *test = &priv->test;
    587	char *fifo_buffer;
    588	int i;
    589
    590	dev_dbg(
    591		&priv->spi->dev,
    592		"test_interface: Buffering upstream message:\n"
    593	);
    594	for (i = 0; i < len; i++)
    595		dev_dbg(&priv->spi->dev, "%#03x\n", buf[i]);
    596
    597	fifo_buffer = kmemdup(buf, len, GFP_KERNEL);
    598	if (!fifo_buffer)
    599		return -ENOMEM;
    600	kfifo_in(&test->up_fifo, &fifo_buffer, 4);
    601	wake_up_interruptible(&priv->test.readq);
    602
    603	return 0;
    604}
    605
    606/* SPI Operation */
    607
    608static int ca8210_net_rx(
    609	struct ieee802154_hw  *hw,
    610	u8                    *command,
    611	size_t                 len
    612);
    613static u8 mlme_reset_request_sync(
    614	u8       set_default_pib,
    615	void    *device_ref
    616);
    617static int ca8210_spi_transfer(
    618	struct spi_device *spi,
    619	const u8          *buf,
    620	size_t             len
    621);
    622
    623/**
    624 * ca8210_reset_send() - Hard resets the ca8210 for a given time
    625 * @spi:  Pointer to target ca8210 spi device
    626 * @ms:   Milliseconds to hold the reset line low for
    627 */
    628static void ca8210_reset_send(struct spi_device *spi, unsigned int ms)
    629{
    630	struct ca8210_platform_data *pdata = spi->dev.platform_data;
    631	struct ca8210_priv *priv = spi_get_drvdata(spi);
    632	long status;
    633
    634	gpio_set_value(pdata->gpio_reset, 0);
    635	reinit_completion(&priv->ca8210_is_awake);
    636	msleep(ms);
    637	gpio_set_value(pdata->gpio_reset, 1);
    638	priv->promiscuous = false;
    639
    640	/* Wait until wakeup indication seen */
    641	status = wait_for_completion_interruptible_timeout(
    642		&priv->ca8210_is_awake,
    643		msecs_to_jiffies(CA8210_SYNC_TIMEOUT)
    644	);
    645	if (status == 0) {
    646		dev_crit(
    647			&spi->dev,
    648			"Fatal: No wakeup from ca8210 after reset!\n"
    649		);
    650	}
    651
    652	dev_dbg(&spi->dev, "Reset the device\n");
    653}
    654
    655/**
    656 * ca8210_mlme_reset_worker() - Resets the MLME, Called when the MAC OVERFLOW
    657 *                              condition happens.
    658 * @work:  Pointer to work being executed
    659 */
    660static void ca8210_mlme_reset_worker(struct work_struct *work)
    661{
    662	struct work_priv_container *wpc = container_of(
    663		work,
    664		struct work_priv_container,
    665		work
    666	);
    667	struct ca8210_priv *priv = wpc->priv;
    668
    669	mlme_reset_request_sync(0, priv->spi);
    670	kfree(wpc);
    671}
    672
    673/**
    674 * ca8210_rx_done() - Calls various message dispatches responding to a received
    675 *                    command
    676 * @cas_ctl: Pointer to the cas_control object for the relevant spi transfer
    677 *
    678 * Presents a received SAP command from the ca8210 to the Cascoda EVBME, test
    679 * interface and network driver.
    680 */
    681static void ca8210_rx_done(struct cas_control *cas_ctl)
    682{
    683	u8 *buf;
    684	unsigned int len;
    685	struct work_priv_container *mlme_reset_wpc;
    686	struct ca8210_priv *priv = cas_ctl->priv;
    687
    688	buf = cas_ctl->tx_in_buf;
    689	len = buf[1] + 2;
    690	if (len > CA8210_SPI_BUF_SIZE) {
    691		dev_crit(
    692			&priv->spi->dev,
    693			"Received packet len (%u) erroneously long\n",
    694			len
    695		);
    696		goto finish;
    697	}
    698
    699	if (buf[0] & SPI_SYN) {
    700		if (priv->sync_command_response) {
    701			memcpy(priv->sync_command_response, buf, len);
    702			complete(&priv->sync_exchange_complete);
    703		} else {
    704			if (cascoda_api_upstream)
    705				cascoda_api_upstream(buf, len, priv->spi);
    706			priv->sync_up++;
    707		}
    708	} else {
    709		if (cascoda_api_upstream)
    710			cascoda_api_upstream(buf, len, priv->spi);
    711	}
    712
    713	ca8210_net_rx(priv->hw, buf, len);
    714	if (buf[0] == SPI_MCPS_DATA_CONFIRM) {
    715		if (buf[3] == IEEE802154_TRANSACTION_OVERFLOW) {
    716			dev_info(
    717				&priv->spi->dev,
    718				"Waiting for transaction overflow to stabilise...\n");
    719			msleep(2000);
    720			dev_info(
    721				&priv->spi->dev,
    722				"Resetting MAC...\n");
    723
    724			mlme_reset_wpc = kmalloc(sizeof(*mlme_reset_wpc),
    725						 GFP_KERNEL);
    726			if (!mlme_reset_wpc)
    727				goto finish;
    728			INIT_WORK(
    729				&mlme_reset_wpc->work,
    730				ca8210_mlme_reset_worker
    731			);
    732			mlme_reset_wpc->priv = priv;
    733			queue_work(priv->mlme_workqueue, &mlme_reset_wpc->work);
    734		}
    735	} else if (buf[0] == SPI_HWME_WAKEUP_INDICATION) {
    736		dev_notice(
    737			&priv->spi->dev,
    738			"Wakeup indication received, reason:\n"
    739		);
    740		switch (buf[2]) {
    741		case 0:
    742			dev_notice(
    743				&priv->spi->dev,
    744				"Transceiver woken up from Power Up / System Reset\n"
    745			);
    746			break;
    747		case 1:
    748			dev_notice(
    749				&priv->spi->dev,
    750				"Watchdog Timer Time-Out\n"
    751			);
    752			break;
    753		case 2:
    754			dev_notice(
    755				&priv->spi->dev,
    756				"Transceiver woken up from Power-Off by Sleep Timer Time-Out\n");
    757			break;
    758		case 3:
    759			dev_notice(
    760				&priv->spi->dev,
    761				"Transceiver woken up from Power-Off by GPIO Activity\n"
    762			);
    763			break;
    764		case 4:
    765			dev_notice(
    766				&priv->spi->dev,
    767				"Transceiver woken up from Standby by Sleep Timer Time-Out\n"
    768			);
    769			break;
    770		case 5:
    771			dev_notice(
    772				&priv->spi->dev,
    773				"Transceiver woken up from Standby by GPIO Activity\n"
    774			);
    775			break;
    776		case 6:
    777			dev_notice(
    778				&priv->spi->dev,
    779				"Sleep-Timer Time-Out in Active Mode\n"
    780			);
    781			break;
    782		default:
    783			dev_warn(&priv->spi->dev, "Wakeup reason unknown\n");
    784			break;
    785		}
    786		complete(&priv->ca8210_is_awake);
    787	}
    788
    789finish:;
    790}
    791
    792static void ca8210_remove(struct spi_device *spi_device);
    793
    794/**
    795 * ca8210_spi_transfer_complete() - Called when a single spi transfer has
    796 *                                  completed
    797 * @context:  Pointer to the cas_control object for the finished transfer
    798 */
    799static void ca8210_spi_transfer_complete(void *context)
    800{
    801	struct cas_control *cas_ctl = context;
    802	struct ca8210_priv *priv = cas_ctl->priv;
    803	bool duplex_rx = false;
    804	int i;
    805	u8 retry_buffer[CA8210_SPI_BUF_SIZE];
    806
    807	if (
    808		cas_ctl->tx_in_buf[0] == SPI_NACK ||
    809		(cas_ctl->tx_in_buf[0] == SPI_IDLE &&
    810		cas_ctl->tx_in_buf[1] == SPI_NACK)
    811	) {
    812		/* ca8210 is busy */
    813		dev_info(&priv->spi->dev, "ca8210 was busy during attempted write\n");
    814		if (cas_ctl->tx_buf[0] == SPI_IDLE) {
    815			dev_warn(
    816				&priv->spi->dev,
    817				"IRQ servicing NACKd, dropping transfer\n"
    818			);
    819			kfree(cas_ctl);
    820			return;
    821		}
    822		if (priv->retries > 3) {
    823			dev_err(&priv->spi->dev, "too many retries!\n");
    824			kfree(cas_ctl);
    825			ca8210_remove(priv->spi);
    826			return;
    827		}
    828		memcpy(retry_buffer, cas_ctl->tx_buf, CA8210_SPI_BUF_SIZE);
    829		kfree(cas_ctl);
    830		ca8210_spi_transfer(
    831			priv->spi,
    832			retry_buffer,
    833			CA8210_SPI_BUF_SIZE
    834		);
    835		priv->retries++;
    836		dev_info(&priv->spi->dev, "retried spi write\n");
    837		return;
    838	} else if (
    839			cas_ctl->tx_in_buf[0] != SPI_IDLE &&
    840			cas_ctl->tx_in_buf[0] != SPI_NACK
    841		) {
    842		duplex_rx = true;
    843	}
    844
    845	if (duplex_rx) {
    846		dev_dbg(&priv->spi->dev, "READ CMD DURING TX\n");
    847		for (i = 0; i < cas_ctl->tx_in_buf[1] + 2; i++)
    848			dev_dbg(
    849				&priv->spi->dev,
    850				"%#03x\n",
    851				cas_ctl->tx_in_buf[i]
    852			);
    853		ca8210_rx_done(cas_ctl);
    854	}
    855	complete(&priv->spi_transfer_complete);
    856	kfree(cas_ctl);
    857	priv->retries = 0;
    858}
    859
    860/**
    861 * ca8210_spi_transfer() - Initiate duplex spi transfer with ca8210
    862 * @spi: Pointer to spi device for transfer
    863 * @buf: Octet array to send
    864 * @len: length of the buffer being sent
    865 *
    866 * Return: 0 or linux error code
    867 */
    868static int ca8210_spi_transfer(
    869	struct spi_device  *spi,
    870	const u8           *buf,
    871	size_t              len
    872)
    873{
    874	int i, status = 0;
    875	struct ca8210_priv *priv;
    876	struct cas_control *cas_ctl;
    877
    878	if (!spi) {
    879		pr_crit("NULL spi device passed to %s\n", __func__);
    880		return -ENODEV;
    881	}
    882
    883	priv = spi_get_drvdata(spi);
    884	reinit_completion(&priv->spi_transfer_complete);
    885
    886	dev_dbg(&spi->dev, "%s called\n", __func__);
    887
    888	cas_ctl = kmalloc(sizeof(*cas_ctl), GFP_ATOMIC);
    889	if (!cas_ctl)
    890		return -ENOMEM;
    891
    892	cas_ctl->priv = priv;
    893	memset(cas_ctl->tx_buf, SPI_IDLE, CA8210_SPI_BUF_SIZE);
    894	memset(cas_ctl->tx_in_buf, SPI_IDLE, CA8210_SPI_BUF_SIZE);
    895	memcpy(cas_ctl->tx_buf, buf, len);
    896
    897	for (i = 0; i < len; i++)
    898		dev_dbg(&spi->dev, "%#03x\n", cas_ctl->tx_buf[i]);
    899
    900	spi_message_init(&cas_ctl->msg);
    901
    902	cas_ctl->transfer.tx_nbits = 1; /* 1 MOSI line */
    903	cas_ctl->transfer.rx_nbits = 1; /* 1 MISO line */
    904	cas_ctl->transfer.speed_hz = 0; /* Use device setting */
    905	cas_ctl->transfer.bits_per_word = 0; /* Use device setting */
    906	cas_ctl->transfer.tx_buf = cas_ctl->tx_buf;
    907	cas_ctl->transfer.rx_buf = cas_ctl->tx_in_buf;
    908	cas_ctl->transfer.delay.value = 0;
    909	cas_ctl->transfer.delay.unit = SPI_DELAY_UNIT_USECS;
    910	cas_ctl->transfer.cs_change = 0;
    911	cas_ctl->transfer.len = sizeof(struct mac_message);
    912	cas_ctl->msg.complete = ca8210_spi_transfer_complete;
    913	cas_ctl->msg.context = cas_ctl;
    914
    915	spi_message_add_tail(
    916		&cas_ctl->transfer,
    917		&cas_ctl->msg
    918	);
    919
    920	status = spi_async(spi, &cas_ctl->msg);
    921	if (status < 0) {
    922		dev_crit(
    923			&spi->dev,
    924			"status %d from spi_sync in write\n",
    925			status
    926		);
    927	}
    928
    929	return status;
    930}
    931
    932/**
    933 * ca8210_spi_exchange() - Exchange API/SAP commands with the radio
    934 * @buf:         Octet array of command being sent downstream
    935 * @len:         length of buf
    936 * @response:    buffer for storing synchronous response
    937 * @device_ref:  spi_device pointer for ca8210
    938 *
    939 * Effectively calls ca8210_spi_transfer to write buf[] to the spi, then for
    940 * synchronous commands waits for the corresponding response to be read from
    941 * the spi before returning. The response is written to the response parameter.
    942 *
    943 * Return: 0 or linux error code
    944 */
    945static int ca8210_spi_exchange(
    946	const u8 *buf,
    947	size_t len,
    948	u8 *response,
    949	void *device_ref
    950)
    951{
    952	int status = 0;
    953	struct spi_device *spi = device_ref;
    954	struct ca8210_priv *priv = spi->dev.driver_data;
    955	long wait_remaining;
    956
    957	if ((buf[0] & SPI_SYN) && response) { /* if sync wait for confirm */
    958		reinit_completion(&priv->sync_exchange_complete);
    959		priv->sync_command_response = response;
    960	}
    961
    962	do {
    963		reinit_completion(&priv->spi_transfer_complete);
    964		status = ca8210_spi_transfer(priv->spi, buf, len);
    965		if (status) {
    966			dev_warn(
    967				&spi->dev,
    968				"spi write failed, returned %d\n",
    969				status
    970			);
    971			if (status == -EBUSY)
    972				continue;
    973			if (((buf[0] & SPI_SYN) && response))
    974				complete(&priv->sync_exchange_complete);
    975			goto cleanup;
    976		}
    977
    978		wait_remaining = wait_for_completion_interruptible_timeout(
    979			&priv->spi_transfer_complete,
    980			msecs_to_jiffies(1000)
    981		);
    982		if (wait_remaining == -ERESTARTSYS) {
    983			status = -ERESTARTSYS;
    984		} else if (wait_remaining == 0) {
    985			dev_err(
    986				&spi->dev,
    987				"SPI downstream transfer timed out!\n"
    988			);
    989			status = -ETIME;
    990			goto cleanup;
    991		}
    992	} while (status < 0);
    993
    994	if (!((buf[0] & SPI_SYN) && response))
    995		goto cleanup;
    996
    997	wait_remaining = wait_for_completion_interruptible_timeout(
    998		&priv->sync_exchange_complete,
    999		msecs_to_jiffies(CA8210_SYNC_TIMEOUT)
   1000	);
   1001	if (wait_remaining == -ERESTARTSYS) {
   1002		status = -ERESTARTSYS;
   1003	} else if (wait_remaining == 0) {
   1004		dev_err(
   1005			&spi->dev,
   1006			"Synchronous confirm timeout\n"
   1007		);
   1008		status = -ETIME;
   1009	}
   1010
   1011cleanup:
   1012	priv->sync_command_response = NULL;
   1013	return status;
   1014}
   1015
   1016/**
   1017 * ca8210_interrupt_handler() - Called when an irq is received from the ca8210
   1018 * @irq:     Id of the irq being handled
   1019 * @dev_id:  Pointer passed by the system, pointing to the ca8210's private data
   1020 *
   1021 * This function is called when the irq line from the ca8210 is asserted,
   1022 * signifying that the ca8210 has a message to send upstream to us. Starts the
   1023 * asynchronous spi read.
   1024 *
   1025 * Return: irq return code
   1026 */
   1027static irqreturn_t ca8210_interrupt_handler(int irq, void *dev_id)
   1028{
   1029	struct ca8210_priv *priv = dev_id;
   1030	int status;
   1031
   1032	dev_dbg(&priv->spi->dev, "irq: Interrupt occurred\n");
   1033	do {
   1034		status = ca8210_spi_transfer(priv->spi, NULL, 0);
   1035		if (status && (status != -EBUSY)) {
   1036			dev_warn(
   1037				&priv->spi->dev,
   1038				"spi read failed, returned %d\n",
   1039				status
   1040			);
   1041		}
   1042	} while (status == -EBUSY);
   1043	return IRQ_HANDLED;
   1044}
   1045
   1046static int (*cascoda_api_downstream)(
   1047	const u8 *buf,
   1048	size_t len,
   1049	u8 *response,
   1050	void *device_ref
   1051) = ca8210_spi_exchange;
   1052
   1053/* Cascoda API / 15.4 SAP Primitives */
   1054
   1055/**
   1056 * tdme_setsfr_request_sync() - TDME_SETSFR_request/confirm according to API
   1057 * @sfr_page:    SFR Page
   1058 * @sfr_address: SFR Address
   1059 * @sfr_value:   SFR Value
   1060 * @device_ref:  Nondescript pointer to target device
   1061 *
   1062 * Return: 802.15.4 status code of TDME-SETSFR.confirm
   1063 */
   1064static u8 tdme_setsfr_request_sync(
   1065	u8            sfr_page,
   1066	u8            sfr_address,
   1067	u8            sfr_value,
   1068	void         *device_ref
   1069)
   1070{
   1071	int ret;
   1072	struct mac_message command, response;
   1073	struct spi_device *spi = device_ref;
   1074
   1075	command.command_id = SPI_TDME_SETSFR_REQUEST;
   1076	command.length = 3;
   1077	command.pdata.tdme_set_sfr_req.sfr_page    = sfr_page;
   1078	command.pdata.tdme_set_sfr_req.sfr_address = sfr_address;
   1079	command.pdata.tdme_set_sfr_req.sfr_value   = sfr_value;
   1080	response.command_id = SPI_IDLE;
   1081	ret = cascoda_api_downstream(
   1082		&command.command_id,
   1083		command.length + 2,
   1084		&response.command_id,
   1085		device_ref
   1086	);
   1087	if (ret) {
   1088		dev_crit(&spi->dev, "cascoda_api_downstream returned %d", ret);
   1089		return IEEE802154_SYSTEM_ERROR;
   1090	}
   1091
   1092	if (response.command_id != SPI_TDME_SETSFR_CONFIRM) {
   1093		dev_crit(
   1094			&spi->dev,
   1095			"sync response to SPI_TDME_SETSFR_REQUEST was not SPI_TDME_SETSFR_CONFIRM, it was %d\n",
   1096			response.command_id
   1097		);
   1098		return IEEE802154_SYSTEM_ERROR;
   1099	}
   1100
   1101	return response.pdata.tdme_set_sfr_cnf.status;
   1102}
   1103
   1104/**
   1105 * tdme_chipinit() - TDME Chip Register Default Initialisation Macro
   1106 * @device_ref: Nondescript pointer to target device
   1107 *
   1108 * Return: 802.15.4 status code of API calls
   1109 */
   1110static u8 tdme_chipinit(void *device_ref)
   1111{
   1112	u8 status = IEEE802154_SUCCESS;
   1113	u8 sfr_address;
   1114	struct spi_device *spi = device_ref;
   1115	struct preamble_cfg_sfr pre_cfg_value = {
   1116		.timeout_symbols     = 3,
   1117		.acquisition_symbols = 3,
   1118		.search_symbols      = 1,
   1119	};
   1120	/* LNA Gain Settings */
   1121	status = tdme_setsfr_request_sync(
   1122		1, (sfr_address = CA8210_SFR_LNAGX40),
   1123		LNAGX40_DEFAULT_GAIN, device_ref);
   1124	if (status)
   1125		goto finish;
   1126	status = tdme_setsfr_request_sync(
   1127		1, (sfr_address = CA8210_SFR_LNAGX41),
   1128		LNAGX41_DEFAULT_GAIN, device_ref);
   1129	if (status)
   1130		goto finish;
   1131	status = tdme_setsfr_request_sync(
   1132		1, (sfr_address = CA8210_SFR_LNAGX42),
   1133		LNAGX42_DEFAULT_GAIN, device_ref);
   1134	if (status)
   1135		goto finish;
   1136	status = tdme_setsfr_request_sync(
   1137		1, (sfr_address = CA8210_SFR_LNAGX43),
   1138		LNAGX43_DEFAULT_GAIN, device_ref);
   1139	if (status)
   1140		goto finish;
   1141	status = tdme_setsfr_request_sync(
   1142		1, (sfr_address = CA8210_SFR_LNAGX44),
   1143		LNAGX44_DEFAULT_GAIN, device_ref);
   1144	if (status)
   1145		goto finish;
   1146	status = tdme_setsfr_request_sync(
   1147		1, (sfr_address = CA8210_SFR_LNAGX45),
   1148		LNAGX45_DEFAULT_GAIN, device_ref);
   1149	if (status)
   1150		goto finish;
   1151	status = tdme_setsfr_request_sync(
   1152		1, (sfr_address = CA8210_SFR_LNAGX46),
   1153		LNAGX46_DEFAULT_GAIN, device_ref);
   1154	if (status)
   1155		goto finish;
   1156	status = tdme_setsfr_request_sync(
   1157		1, (sfr_address = CA8210_SFR_LNAGX47),
   1158		LNAGX47_DEFAULT_GAIN, device_ref);
   1159	if (status)
   1160		goto finish;
   1161	/* Preamble Timing Config */
   1162	status = tdme_setsfr_request_sync(
   1163		1, (sfr_address = CA8210_SFR_PRECFG),
   1164		*((u8 *)&pre_cfg_value), device_ref);
   1165	if (status)
   1166		goto finish;
   1167	/* Preamble Threshold High */
   1168	status = tdme_setsfr_request_sync(
   1169		1, (sfr_address = CA8210_SFR_PTHRH),
   1170		PTHRH_DEFAULT_THRESHOLD, device_ref);
   1171	if (status)
   1172		goto finish;
   1173	/* Tx Output Power 8 dBm */
   1174	status = tdme_setsfr_request_sync(
   1175		0, (sfr_address = CA8210_SFR_PACFGIB),
   1176		PACFGIB_DEFAULT_CURRENT, device_ref);
   1177	if (status)
   1178		goto finish;
   1179
   1180finish:
   1181	if (status != IEEE802154_SUCCESS) {
   1182		dev_err(
   1183			&spi->dev,
   1184			"failed to set sfr at %#03x, status = %#03x\n",
   1185			sfr_address,
   1186			status
   1187		);
   1188	}
   1189	return status;
   1190}
   1191
   1192/**
   1193 * tdme_channelinit() - TDME Channel Register Default Initialisation Macro (Tx)
   1194 * @channel:    802.15.4 channel to initialise chip for
   1195 * @device_ref: Nondescript pointer to target device
   1196 *
   1197 * Return: 802.15.4 status code of API calls
   1198 */
   1199static u8 tdme_channelinit(u8 channel, void *device_ref)
   1200{
   1201	/* Transceiver front-end local oscillator tx two-point calibration
   1202	 * value. Tuned for the hardware.
   1203	 */
   1204	u8 txcalval;
   1205
   1206	if (channel >= 25)
   1207		txcalval = 0xA7;
   1208	else if (channel >= 23)
   1209		txcalval = 0xA8;
   1210	else if (channel >= 22)
   1211		txcalval = 0xA9;
   1212	else if (channel >= 20)
   1213		txcalval = 0xAA;
   1214	else if (channel >= 17)
   1215		txcalval = 0xAB;
   1216	else if (channel >= 16)
   1217		txcalval = 0xAC;
   1218	else if (channel >= 14)
   1219		txcalval = 0xAD;
   1220	else if (channel >= 12)
   1221		txcalval = 0xAE;
   1222	else
   1223		txcalval = 0xAF;
   1224
   1225	return tdme_setsfr_request_sync(
   1226		1,
   1227		CA8210_SFR_LOTXCAL,
   1228		txcalval,
   1229		device_ref
   1230	);  /* LO Tx Cal */
   1231}
   1232
   1233/**
   1234 * tdme_checkpibattribute() - Checks Attribute Values that are not checked in
   1235 *                            MAC
   1236 * @pib_attribute:        Attribute Number
   1237 * @pib_attribute_length: Attribute length
   1238 * @pib_attribute_value:  Pointer to Attribute Value
   1239 *
   1240 * Return: 802.15.4 status code of checks
   1241 */
   1242static u8 tdme_checkpibattribute(
   1243	u8            pib_attribute,
   1244	u8            pib_attribute_length,
   1245	const void   *pib_attribute_value
   1246)
   1247{
   1248	u8 status = IEEE802154_SUCCESS;
   1249	u8 value;
   1250
   1251	value  = *((u8 *)pib_attribute_value);
   1252
   1253	switch (pib_attribute) {
   1254	/* PHY */
   1255	case PHY_TRANSMIT_POWER:
   1256		if (value > 0x3F)
   1257			status = IEEE802154_INVALID_PARAMETER;
   1258		break;
   1259	case PHY_CCA_MODE:
   1260		if (value > 0x03)
   1261			status = IEEE802154_INVALID_PARAMETER;
   1262		break;
   1263	/* MAC */
   1264	case MAC_BATT_LIFE_EXT_PERIODS:
   1265		if (value < 6 || value > 41)
   1266			status = IEEE802154_INVALID_PARAMETER;
   1267		break;
   1268	case MAC_BEACON_PAYLOAD:
   1269		if (pib_attribute_length > MAX_BEACON_PAYLOAD_LENGTH)
   1270			status = IEEE802154_INVALID_PARAMETER;
   1271		break;
   1272	case MAC_BEACON_PAYLOAD_LENGTH:
   1273		if (value > MAX_BEACON_PAYLOAD_LENGTH)
   1274			status = IEEE802154_INVALID_PARAMETER;
   1275		break;
   1276	case MAC_BEACON_ORDER:
   1277		if (value > 15)
   1278			status = IEEE802154_INVALID_PARAMETER;
   1279		break;
   1280	case MAC_MAX_BE:
   1281		if (value < 3 || value > 8)
   1282			status = IEEE802154_INVALID_PARAMETER;
   1283		break;
   1284	case MAC_MAX_CSMA_BACKOFFS:
   1285		if (value > 5)
   1286			status = IEEE802154_INVALID_PARAMETER;
   1287		break;
   1288	case MAC_MAX_FRAME_RETRIES:
   1289		if (value > 7)
   1290			status = IEEE802154_INVALID_PARAMETER;
   1291		break;
   1292	case MAC_MIN_BE:
   1293		if (value > 8)
   1294			status = IEEE802154_INVALID_PARAMETER;
   1295		break;
   1296	case MAC_RESPONSE_WAIT_TIME:
   1297		if (value < 2 || value > 64)
   1298			status = IEEE802154_INVALID_PARAMETER;
   1299		break;
   1300	case MAC_SUPERFRAME_ORDER:
   1301		if (value > 15)
   1302			status = IEEE802154_INVALID_PARAMETER;
   1303		break;
   1304	/* boolean */
   1305	case MAC_ASSOCIATED_PAN_COORD:
   1306	case MAC_ASSOCIATION_PERMIT:
   1307	case MAC_AUTO_REQUEST:
   1308	case MAC_BATT_LIFE_EXT:
   1309	case MAC_GTS_PERMIT:
   1310	case MAC_PROMISCUOUS_MODE:
   1311	case MAC_RX_ON_WHEN_IDLE:
   1312	case MAC_SECURITY_ENABLED:
   1313		if (value > 1)
   1314			status = IEEE802154_INVALID_PARAMETER;
   1315		break;
   1316	/* MAC SEC */
   1317	case MAC_AUTO_REQUEST_SECURITY_LEVEL:
   1318		if (value > 7)
   1319			status = IEEE802154_INVALID_PARAMETER;
   1320		break;
   1321	case MAC_AUTO_REQUEST_KEY_ID_MODE:
   1322		if (value > 3)
   1323			status = IEEE802154_INVALID_PARAMETER;
   1324		break;
   1325	default:
   1326		break;
   1327	}
   1328
   1329	return status;
   1330}
   1331
   1332/**
   1333 * tdme_settxpower() - Sets the tx power for MLME_SET phyTransmitPower
   1334 * @txp:        Transmit Power
   1335 * @device_ref: Nondescript pointer to target device
   1336 *
   1337 * Normalised to 802.15.4 Definition (6-bit, signed):
   1338 * Bit 7-6: not used
   1339 * Bit 5-0: tx power (-32 - +31 dB)
   1340 *
   1341 * Return: 802.15.4 status code of api calls
   1342 */
   1343static u8 tdme_settxpower(u8 txp, void *device_ref)
   1344{
   1345	u8 status;
   1346	s8 txp_val;
   1347	u8 txp_ext;
   1348	union pa_cfg_sfr pa_cfg_val;
   1349
   1350	/* extend from 6 to 8 bit */
   1351	txp_ext = 0x3F & txp;
   1352	if (txp_ext & 0x20)
   1353		txp_ext += 0xC0;
   1354	txp_val = (s8)txp_ext;
   1355
   1356	if (CA8210_MAC_MPW) {
   1357		if (txp_val > 0) {
   1358			/* 8 dBm: ptrim = 5, itrim = +3 => +4 dBm */
   1359			pa_cfg_val.bias_current_trim     = 3;
   1360			pa_cfg_val.buffer_capacitor_trim = 5;
   1361			pa_cfg_val.boost                 = 1;
   1362		} else {
   1363			/* 0 dBm: ptrim = 7, itrim = +3 => -6 dBm */
   1364			pa_cfg_val.bias_current_trim     = 3;
   1365			pa_cfg_val.buffer_capacitor_trim = 7;
   1366			pa_cfg_val.boost                 = 0;
   1367		}
   1368		/* write PACFG */
   1369		status = tdme_setsfr_request_sync(
   1370			0,
   1371			CA8210_SFR_PACFG,
   1372			pa_cfg_val.paib,
   1373			device_ref
   1374		);
   1375	} else {
   1376		/* Look-Up Table for Setting Current and Frequency Trim values
   1377		 * for desired Output Power
   1378		 */
   1379		if (txp_val > 8) {
   1380			pa_cfg_val.paib = 0x3F;
   1381		} else if (txp_val == 8) {
   1382			pa_cfg_val.paib = 0x32;
   1383		} else if (txp_val == 7) {
   1384			pa_cfg_val.paib = 0x22;
   1385		} else if (txp_val == 6) {
   1386			pa_cfg_val.paib = 0x18;
   1387		} else if (txp_val == 5) {
   1388			pa_cfg_val.paib = 0x10;
   1389		} else if (txp_val == 4) {
   1390			pa_cfg_val.paib = 0x0C;
   1391		} else if (txp_val == 3) {
   1392			pa_cfg_val.paib = 0x08;
   1393		} else if (txp_val == 2) {
   1394			pa_cfg_val.paib = 0x05;
   1395		} else if (txp_val == 1) {
   1396			pa_cfg_val.paib = 0x03;
   1397		} else if (txp_val == 0) {
   1398			pa_cfg_val.paib = 0x01;
   1399		} else { /* < 0 */
   1400			pa_cfg_val.paib = 0x00;
   1401		}
   1402		/* write PACFGIB */
   1403		status = tdme_setsfr_request_sync(
   1404			0,
   1405			CA8210_SFR_PACFGIB,
   1406			pa_cfg_val.paib,
   1407			device_ref
   1408		);
   1409	}
   1410
   1411	return status;
   1412}
   1413
   1414/**
   1415 * mcps_data_request() - mcps_data_request (Send Data) according to API Spec
   1416 * @src_addr_mode:    Source Addressing Mode
   1417 * @dst_address_mode: Destination Addressing Mode
   1418 * @dst_pan_id:       Destination PAN ID
   1419 * @dst_addr:         Pointer to Destination Address
   1420 * @msdu_length:      length of Data
   1421 * @msdu:             Pointer to Data
   1422 * @msdu_handle:      Handle of Data
   1423 * @tx_options:       Tx Options Bit Field
   1424 * @security:         Pointer to Security Structure or NULL
   1425 * @device_ref:       Nondescript pointer to target device
   1426 *
   1427 * Return: 802.15.4 status code of action
   1428 */
   1429static u8 mcps_data_request(
   1430	u8               src_addr_mode,
   1431	u8               dst_address_mode,
   1432	u16              dst_pan_id,
   1433	union macaddr   *dst_addr,
   1434	u8               msdu_length,
   1435	u8              *msdu,
   1436	u8               msdu_handle,
   1437	u8               tx_options,
   1438	struct secspec  *security,
   1439	void            *device_ref
   1440)
   1441{
   1442	struct secspec *psec;
   1443	struct mac_message command;
   1444
   1445	command.command_id = SPI_MCPS_DATA_REQUEST;
   1446	command.pdata.data_req.src_addr_mode = src_addr_mode;
   1447	command.pdata.data_req.dst.mode = dst_address_mode;
   1448	if (dst_address_mode != MAC_MODE_NO_ADDR) {
   1449		command.pdata.data_req.dst.pan_id[0] = LS_BYTE(dst_pan_id);
   1450		command.pdata.data_req.dst.pan_id[1] = MS_BYTE(dst_pan_id);
   1451		if (dst_address_mode == MAC_MODE_SHORT_ADDR) {
   1452			command.pdata.data_req.dst.address[0] = LS_BYTE(
   1453				dst_addr->short_address
   1454			);
   1455			command.pdata.data_req.dst.address[1] = MS_BYTE(
   1456				dst_addr->short_address
   1457			);
   1458		} else {   /* MAC_MODE_LONG_ADDR*/
   1459			memcpy(
   1460				command.pdata.data_req.dst.address,
   1461				dst_addr->ieee_address,
   1462				8
   1463			);
   1464		}
   1465	}
   1466	command.pdata.data_req.msdu_length = msdu_length;
   1467	command.pdata.data_req.msdu_handle = msdu_handle;
   1468	command.pdata.data_req.tx_options = tx_options;
   1469	memcpy(command.pdata.data_req.msdu, msdu, msdu_length);
   1470	psec = (struct secspec *)(command.pdata.data_req.msdu + msdu_length);
   1471	command.length = sizeof(struct mcps_data_request_pset) -
   1472		MAX_DATA_SIZE + msdu_length;
   1473	if (!security || security->security_level == 0) {
   1474		psec->security_level = 0;
   1475		command.length += 1;
   1476	} else {
   1477		*psec = *security;
   1478		command.length += sizeof(struct secspec);
   1479	}
   1480
   1481	if (ca8210_spi_transfer(device_ref, &command.command_id,
   1482				command.length + 2))
   1483		return IEEE802154_SYSTEM_ERROR;
   1484
   1485	return IEEE802154_SUCCESS;
   1486}
   1487
   1488/**
   1489 * mlme_reset_request_sync() - MLME_RESET_request/confirm according to API Spec
   1490 * @set_default_pib: Set defaults in PIB
   1491 * @device_ref:      Nondescript pointer to target device
   1492 *
   1493 * Return: 802.15.4 status code of MLME-RESET.confirm
   1494 */
   1495static u8 mlme_reset_request_sync(
   1496	u8    set_default_pib,
   1497	void *device_ref
   1498)
   1499{
   1500	u8 status;
   1501	struct mac_message command, response;
   1502	struct spi_device *spi = device_ref;
   1503
   1504	command.command_id = SPI_MLME_RESET_REQUEST;
   1505	command.length = 1;
   1506	command.pdata.u8param = set_default_pib;
   1507
   1508	if (cascoda_api_downstream(
   1509		&command.command_id,
   1510		command.length + 2,
   1511		&response.command_id,
   1512		device_ref)) {
   1513		dev_err(&spi->dev, "cascoda_api_downstream failed\n");
   1514		return IEEE802154_SYSTEM_ERROR;
   1515	}
   1516
   1517	if (response.command_id != SPI_MLME_RESET_CONFIRM)
   1518		return IEEE802154_SYSTEM_ERROR;
   1519
   1520	status = response.pdata.status;
   1521
   1522	/* reset COORD Bit for Channel Filtering as Coordinator */
   1523	if (CA8210_MAC_WORKAROUNDS && set_default_pib && !status) {
   1524		status = tdme_setsfr_request_sync(
   1525			0,
   1526			CA8210_SFR_MACCON,
   1527			0,
   1528			device_ref
   1529		);
   1530	}
   1531
   1532	return status;
   1533}
   1534
   1535/**
   1536 * mlme_set_request_sync() - MLME_SET_request/confirm according to API Spec
   1537 * @pib_attribute:        Attribute Number
   1538 * @pib_attribute_index:  Index within Attribute if an Array
   1539 * @pib_attribute_length: Attribute length
   1540 * @pib_attribute_value:  Pointer to Attribute Value
   1541 * @device_ref:           Nondescript pointer to target device
   1542 *
   1543 * Return: 802.15.4 status code of MLME-SET.confirm
   1544 */
   1545static u8 mlme_set_request_sync(
   1546	u8            pib_attribute,
   1547	u8            pib_attribute_index,
   1548	u8            pib_attribute_length,
   1549	const void   *pib_attribute_value,
   1550	void         *device_ref
   1551)
   1552{
   1553	u8 status;
   1554	struct mac_message command, response;
   1555
   1556	/* pre-check the validity of pib_attribute values that are not checked
   1557	 * in MAC
   1558	 */
   1559	if (tdme_checkpibattribute(
   1560		pib_attribute, pib_attribute_length, pib_attribute_value)) {
   1561		return IEEE802154_INVALID_PARAMETER;
   1562	}
   1563
   1564	if (pib_attribute == PHY_CURRENT_CHANNEL) {
   1565		status = tdme_channelinit(
   1566			*((u8 *)pib_attribute_value),
   1567			device_ref
   1568		);
   1569		if (status)
   1570			return status;
   1571	}
   1572
   1573	if (pib_attribute == PHY_TRANSMIT_POWER) {
   1574		return tdme_settxpower(
   1575			*((u8 *)pib_attribute_value),
   1576			device_ref
   1577		);
   1578	}
   1579
   1580	command.command_id = SPI_MLME_SET_REQUEST;
   1581	command.length = sizeof(struct mlme_set_request_pset) -
   1582		MAX_ATTRIBUTE_SIZE + pib_attribute_length;
   1583	command.pdata.set_req.pib_attribute = pib_attribute;
   1584	command.pdata.set_req.pib_attribute_index = pib_attribute_index;
   1585	command.pdata.set_req.pib_attribute_length = pib_attribute_length;
   1586	memcpy(
   1587		command.pdata.set_req.pib_attribute_value,
   1588		pib_attribute_value,
   1589		pib_attribute_length
   1590	);
   1591
   1592	if (cascoda_api_downstream(
   1593		&command.command_id,
   1594		command.length + 2,
   1595		&response.command_id,
   1596		device_ref)) {
   1597		return IEEE802154_SYSTEM_ERROR;
   1598	}
   1599
   1600	if (response.command_id != SPI_MLME_SET_CONFIRM)
   1601		return IEEE802154_SYSTEM_ERROR;
   1602
   1603	return response.pdata.status;
   1604}
   1605
   1606/**
   1607 * hwme_set_request_sync() - HWME_SET_request/confirm according to API Spec
   1608 * @hw_attribute:        Attribute Number
   1609 * @hw_attribute_length: Attribute length
   1610 * @hw_attribute_value:  Pointer to Attribute Value
   1611 * @device_ref:          Nondescript pointer to target device
   1612 *
   1613 * Return: 802.15.4 status code of HWME-SET.confirm
   1614 */
   1615static u8 hwme_set_request_sync(
   1616	u8           hw_attribute,
   1617	u8           hw_attribute_length,
   1618	u8          *hw_attribute_value,
   1619	void        *device_ref
   1620)
   1621{
   1622	struct mac_message command, response;
   1623
   1624	command.command_id = SPI_HWME_SET_REQUEST;
   1625	command.length = 2 + hw_attribute_length;
   1626	command.pdata.hwme_set_req.hw_attribute = hw_attribute;
   1627	command.pdata.hwme_set_req.hw_attribute_length = hw_attribute_length;
   1628	memcpy(
   1629		command.pdata.hwme_set_req.hw_attribute_value,
   1630		hw_attribute_value,
   1631		hw_attribute_length
   1632	);
   1633
   1634	if (cascoda_api_downstream(
   1635		&command.command_id,
   1636		command.length + 2,
   1637		&response.command_id,
   1638		device_ref)) {
   1639		return IEEE802154_SYSTEM_ERROR;
   1640	}
   1641
   1642	if (response.command_id != SPI_HWME_SET_CONFIRM)
   1643		return IEEE802154_SYSTEM_ERROR;
   1644
   1645	return response.pdata.hwme_set_cnf.status;
   1646}
   1647
   1648/**
   1649 * hwme_get_request_sync() - HWME_GET_request/confirm according to API Spec
   1650 * @hw_attribute:        Attribute Number
   1651 * @hw_attribute_length: Attribute length
   1652 * @hw_attribute_value:  Pointer to Attribute Value
   1653 * @device_ref:          Nondescript pointer to target device
   1654 *
   1655 * Return: 802.15.4 status code of HWME-GET.confirm
   1656 */
   1657static u8 hwme_get_request_sync(
   1658	u8           hw_attribute,
   1659	u8          *hw_attribute_length,
   1660	u8          *hw_attribute_value,
   1661	void        *device_ref
   1662)
   1663{
   1664	struct mac_message command, response;
   1665
   1666	command.command_id = SPI_HWME_GET_REQUEST;
   1667	command.length = 1;
   1668	command.pdata.hwme_get_req.hw_attribute = hw_attribute;
   1669
   1670	if (cascoda_api_downstream(
   1671		&command.command_id,
   1672		command.length + 2,
   1673		&response.command_id,
   1674		device_ref)) {
   1675		return IEEE802154_SYSTEM_ERROR;
   1676	}
   1677
   1678	if (response.command_id != SPI_HWME_GET_CONFIRM)
   1679		return IEEE802154_SYSTEM_ERROR;
   1680
   1681	if (response.pdata.hwme_get_cnf.status == IEEE802154_SUCCESS) {
   1682		*hw_attribute_length =
   1683			response.pdata.hwme_get_cnf.hw_attribute_length;
   1684		memcpy(
   1685			hw_attribute_value,
   1686			response.pdata.hwme_get_cnf.hw_attribute_value,
   1687			*hw_attribute_length
   1688		);
   1689	}
   1690
   1691	return response.pdata.hwme_get_cnf.status;
   1692}
   1693
   1694/* Network driver operation */
   1695
   1696/**
   1697 * ca8210_async_xmit_complete() - Called to announce that an asynchronous
   1698 *                                transmission has finished
   1699 * @hw:          ieee802154_hw of ca8210 that has finished exchange
   1700 * @msduhandle:  Identifier of transmission that has completed
   1701 * @status:      Returned 802.15.4 status code of the transmission
   1702 *
   1703 * Return: 0 or linux error code
   1704 */
   1705static int ca8210_async_xmit_complete(
   1706	struct ieee802154_hw  *hw,
   1707	u8                     msduhandle,
   1708	u8                     status)
   1709{
   1710	struct ca8210_priv *priv = hw->priv;
   1711
   1712	if (priv->nextmsduhandle != msduhandle) {
   1713		dev_err(
   1714			&priv->spi->dev,
   1715			"Unexpected msdu_handle on data confirm, Expected %d, got %d\n",
   1716			priv->nextmsduhandle,
   1717			msduhandle
   1718		);
   1719		return -EIO;
   1720	}
   1721
   1722	priv->async_tx_pending = false;
   1723	priv->nextmsduhandle++;
   1724
   1725	if (status) {
   1726		dev_err(
   1727			&priv->spi->dev,
   1728			"Link transmission unsuccessful, status = %d\n",
   1729			status
   1730		);
   1731		if (status != IEEE802154_TRANSACTION_OVERFLOW) {
   1732			ieee802154_xmit_error(priv->hw, priv->tx_skb, status);
   1733			return 0;
   1734		}
   1735	}
   1736	ieee802154_xmit_complete(priv->hw, priv->tx_skb, true);
   1737
   1738	return 0;
   1739}
   1740
   1741/**
   1742 * ca8210_skb_rx() - Contructs a properly framed socket buffer from a received
   1743 *                   MCPS_DATA_indication
   1744 * @hw:        ieee802154_hw that MCPS_DATA_indication was received by
   1745 * @len:       length of MCPS_DATA_indication
   1746 * @data_ind:  Octet array of MCPS_DATA_indication
   1747 *
   1748 * Called by the spi driver whenever a SAP command is received, this function
   1749 * will ascertain whether the command is of interest to the network driver and
   1750 * take necessary action.
   1751 *
   1752 * Return: 0 or linux error code
   1753 */
   1754static int ca8210_skb_rx(
   1755	struct ieee802154_hw  *hw,
   1756	size_t                 len,
   1757	u8                    *data_ind
   1758)
   1759{
   1760	struct ieee802154_hdr hdr;
   1761	int msdulen;
   1762	int hlen;
   1763	u8 mpdulinkquality = data_ind[23];
   1764	struct sk_buff *skb;
   1765	struct ca8210_priv *priv = hw->priv;
   1766
   1767	/* Allocate mtu size buffer for every rx packet */
   1768	skb = dev_alloc_skb(IEEE802154_MTU + sizeof(hdr));
   1769	if (!skb)
   1770		return -ENOMEM;
   1771
   1772	skb_reserve(skb, sizeof(hdr));
   1773
   1774	msdulen = data_ind[22]; /* msdu_length */
   1775	if (msdulen > IEEE802154_MTU) {
   1776		dev_err(
   1777			&priv->spi->dev,
   1778			"received erroneously large msdu length!\n"
   1779		);
   1780		kfree_skb(skb);
   1781		return -EMSGSIZE;
   1782	}
   1783	dev_dbg(&priv->spi->dev, "skb buffer length = %d\n", msdulen);
   1784
   1785	if (priv->promiscuous)
   1786		goto copy_payload;
   1787
   1788	/* Populate hdr */
   1789	hdr.sec.level = data_ind[29 + msdulen];
   1790	dev_dbg(&priv->spi->dev, "security level: %#03x\n", hdr.sec.level);
   1791	if (hdr.sec.level > 0) {
   1792		hdr.sec.key_id_mode = data_ind[30 + msdulen];
   1793		memcpy(&hdr.sec.extended_src, &data_ind[31 + msdulen], 8);
   1794		hdr.sec.key_id = data_ind[39 + msdulen];
   1795	}
   1796	hdr.source.mode = data_ind[0];
   1797	dev_dbg(&priv->spi->dev, "srcAddrMode: %#03x\n", hdr.source.mode);
   1798	hdr.source.pan_id = *(u16 *)&data_ind[1];
   1799	dev_dbg(&priv->spi->dev, "srcPanId: %#06x\n", hdr.source.pan_id);
   1800	memcpy(&hdr.source.extended_addr, &data_ind[3], 8);
   1801	hdr.dest.mode = data_ind[11];
   1802	dev_dbg(&priv->spi->dev, "dstAddrMode: %#03x\n", hdr.dest.mode);
   1803	hdr.dest.pan_id = *(u16 *)&data_ind[12];
   1804	dev_dbg(&priv->spi->dev, "dstPanId: %#06x\n", hdr.dest.pan_id);
   1805	memcpy(&hdr.dest.extended_addr, &data_ind[14], 8);
   1806
   1807	/* Fill in FC implicitly */
   1808	hdr.fc.type = 1; /* Data frame */
   1809	if (hdr.sec.level)
   1810		hdr.fc.security_enabled = 1;
   1811	else
   1812		hdr.fc.security_enabled = 0;
   1813	if (data_ind[1] != data_ind[12] || data_ind[2] != data_ind[13])
   1814		hdr.fc.intra_pan = 1;
   1815	else
   1816		hdr.fc.intra_pan = 0;
   1817	hdr.fc.dest_addr_mode = hdr.dest.mode;
   1818	hdr.fc.source_addr_mode = hdr.source.mode;
   1819
   1820	/* Add hdr to front of buffer */
   1821	hlen = ieee802154_hdr_push(skb, &hdr);
   1822
   1823	if (hlen < 0) {
   1824		dev_crit(&priv->spi->dev, "failed to push mac hdr onto skb!\n");
   1825		kfree_skb(skb);
   1826		return hlen;
   1827	}
   1828
   1829	skb_reset_mac_header(skb);
   1830	skb->mac_len = hlen;
   1831
   1832copy_payload:
   1833	/* Add <msdulen> bytes of space to the back of the buffer */
   1834	/* Copy msdu to skb */
   1835	skb_put_data(skb, &data_ind[29], msdulen);
   1836
   1837	ieee802154_rx_irqsafe(hw, skb, mpdulinkquality);
   1838	return 0;
   1839}
   1840
   1841/**
   1842 * ca8210_net_rx() - Acts upon received SAP commands relevant to the network
   1843 *                   driver
   1844 * @hw:       ieee802154_hw that command was received by
   1845 * @command:  Octet array of received command
   1846 * @len:      length of the received command
   1847 *
   1848 * Called by the spi driver whenever a SAP command is received, this function
   1849 * will ascertain whether the command is of interest to the network driver and
   1850 * take necessary action.
   1851 *
   1852 * Return: 0 or linux error code
   1853 */
   1854static int ca8210_net_rx(struct ieee802154_hw *hw, u8 *command, size_t len)
   1855{
   1856	struct ca8210_priv *priv = hw->priv;
   1857	unsigned long flags;
   1858	u8 status;
   1859
   1860	dev_dbg(&priv->spi->dev, "%s: CmdID = %d\n", __func__, command[0]);
   1861
   1862	if (command[0] == SPI_MCPS_DATA_INDICATION) {
   1863		/* Received data */
   1864		spin_lock_irqsave(&priv->lock, flags);
   1865		if (command[26] == priv->last_dsn) {
   1866			dev_dbg(
   1867				&priv->spi->dev,
   1868				"DSN %d resend received, ignoring...\n",
   1869				command[26]
   1870			);
   1871			spin_unlock_irqrestore(&priv->lock, flags);
   1872			return 0;
   1873		}
   1874		priv->last_dsn = command[26];
   1875		spin_unlock_irqrestore(&priv->lock, flags);
   1876		return ca8210_skb_rx(hw, len - 2, command + 2);
   1877	} else if (command[0] == SPI_MCPS_DATA_CONFIRM) {
   1878		status = command[3];
   1879		if (priv->async_tx_pending) {
   1880			return ca8210_async_xmit_complete(
   1881				hw,
   1882				command[2],
   1883				status
   1884			);
   1885		}
   1886	}
   1887
   1888	return 0;
   1889}
   1890
   1891/**
   1892 * ca8210_skb_tx() - Transmits a given socket buffer using the ca8210
   1893 * @skb:         Socket buffer to transmit
   1894 * @msduhandle:  Data identifier to pass to the 802.15.4 MAC
   1895 * @priv:        Pointer to private data section of target ca8210
   1896 *
   1897 * Return: 0 or linux error code
   1898 */
   1899static int ca8210_skb_tx(
   1900	struct sk_buff      *skb,
   1901	u8                   msduhandle,
   1902	struct ca8210_priv  *priv
   1903)
   1904{
   1905	int status;
   1906	struct ieee802154_hdr header = { };
   1907	struct secspec secspec;
   1908	unsigned int mac_len;
   1909
   1910	dev_dbg(&priv->spi->dev, "%s called\n", __func__);
   1911
   1912	/* Get addressing info from skb - ieee802154 layer creates a full
   1913	 * packet
   1914	 */
   1915	mac_len = ieee802154_hdr_peek_addrs(skb, &header);
   1916
   1917	secspec.security_level = header.sec.level;
   1918	secspec.key_id_mode = header.sec.key_id_mode;
   1919	if (secspec.key_id_mode == 2)
   1920		memcpy(secspec.key_source, &header.sec.short_src, 4);
   1921	else if (secspec.key_id_mode == 3)
   1922		memcpy(secspec.key_source, &header.sec.extended_src, 8);
   1923	secspec.key_index = header.sec.key_id;
   1924
   1925	/* Pass to Cascoda API */
   1926	status =  mcps_data_request(
   1927		header.source.mode,
   1928		header.dest.mode,
   1929		header.dest.pan_id,
   1930		(union macaddr *)&header.dest.extended_addr,
   1931		skb->len - mac_len,
   1932		&skb->data[mac_len],
   1933		msduhandle,
   1934		header.fc.ack_request,
   1935		&secspec,
   1936		priv->spi
   1937	);
   1938	return link_to_linux_err(status);
   1939}
   1940
   1941/**
   1942 * ca8210_start() - Starts the network driver
   1943 * @hw:  ieee802154_hw of ca8210 being started
   1944 *
   1945 * Return: 0 or linux error code
   1946 */
   1947static int ca8210_start(struct ieee802154_hw *hw)
   1948{
   1949	int status;
   1950	u8 rx_on_when_idle;
   1951	u8 lqi_threshold = 0;
   1952	struct ca8210_priv *priv = hw->priv;
   1953
   1954	priv->last_dsn = -1;
   1955	/* Turn receiver on when idle for now just to test rx */
   1956	rx_on_when_idle = 1;
   1957	status = mlme_set_request_sync(
   1958		MAC_RX_ON_WHEN_IDLE,
   1959		0,
   1960		1,
   1961		&rx_on_when_idle,
   1962		priv->spi
   1963	);
   1964	if (status) {
   1965		dev_crit(
   1966			&priv->spi->dev,
   1967			"Setting rx_on_when_idle failed, status = %d\n",
   1968			status
   1969		);
   1970		return link_to_linux_err(status);
   1971	}
   1972	status = hwme_set_request_sync(
   1973		HWME_LQILIMIT,
   1974		1,
   1975		&lqi_threshold,
   1976		priv->spi
   1977	);
   1978	if (status) {
   1979		dev_crit(
   1980			&priv->spi->dev,
   1981			"Setting lqilimit failed, status = %d\n",
   1982			status
   1983		);
   1984		return link_to_linux_err(status);
   1985	}
   1986
   1987	return 0;
   1988}
   1989
   1990/**
   1991 * ca8210_stop() - Stops the network driver
   1992 * @hw:  ieee802154_hw of ca8210 being stopped
   1993 *
   1994 * Return: 0 or linux error code
   1995 */
   1996static void ca8210_stop(struct ieee802154_hw *hw)
   1997{
   1998}
   1999
   2000/**
   2001 * ca8210_xmit_async() - Asynchronously transmits a given socket buffer using
   2002 *                       the ca8210
   2003 * @hw:   ieee802154_hw of ca8210 to transmit from
   2004 * @skb:  Socket buffer to transmit
   2005 *
   2006 * Return: 0 or linux error code
   2007 */
   2008static int ca8210_xmit_async(struct ieee802154_hw *hw, struct sk_buff *skb)
   2009{
   2010	struct ca8210_priv *priv = hw->priv;
   2011	int status;
   2012
   2013	dev_dbg(&priv->spi->dev, "calling %s\n", __func__);
   2014
   2015	priv->tx_skb = skb;
   2016	priv->async_tx_pending = true;
   2017	status = ca8210_skb_tx(skb, priv->nextmsduhandle, priv);
   2018	return status;
   2019}
   2020
   2021/**
   2022 * ca8210_get_ed() - Returns the measured energy on the current channel at this
   2023 *                   instant in time
   2024 * @hw:     ieee802154_hw of target ca8210
   2025 * @level:  Measured Energy Detect level
   2026 *
   2027 * Return: 0 or linux error code
   2028 */
   2029static int ca8210_get_ed(struct ieee802154_hw *hw, u8 *level)
   2030{
   2031	u8 lenvar;
   2032	struct ca8210_priv *priv = hw->priv;
   2033
   2034	return link_to_linux_err(
   2035		hwme_get_request_sync(HWME_EDVALUE, &lenvar, level, priv->spi)
   2036	);
   2037}
   2038
   2039/**
   2040 * ca8210_set_channel() - Sets the current operating 802.15.4 channel of the
   2041 *                        ca8210
   2042 * @hw:       ieee802154_hw of target ca8210
   2043 * @page:     Channel page to set
   2044 * @channel:  Channel number to set
   2045 *
   2046 * Return: 0 or linux error code
   2047 */
   2048static int ca8210_set_channel(
   2049	struct ieee802154_hw  *hw,
   2050	u8                     page,
   2051	u8                     channel
   2052)
   2053{
   2054	u8 status;
   2055	struct ca8210_priv *priv = hw->priv;
   2056
   2057	status = mlme_set_request_sync(
   2058		PHY_CURRENT_CHANNEL,
   2059		0,
   2060		1,
   2061		&channel,
   2062		priv->spi
   2063	);
   2064	if (status) {
   2065		dev_err(
   2066			&priv->spi->dev,
   2067			"error setting channel, MLME-SET.confirm status = %d\n",
   2068			status
   2069		);
   2070	}
   2071	return link_to_linux_err(status);
   2072}
   2073
   2074/**
   2075 * ca8210_set_hw_addr_filt() - Sets the address filtering parameters of the
   2076 *                             ca8210
   2077 * @hw:       ieee802154_hw of target ca8210
   2078 * @filt:     Filtering parameters
   2079 * @changed:  Bitmap representing which parameters to change
   2080 *
   2081 * Effectively just sets the actual addressing information identifying this node
   2082 * as all filtering is performed by the ca8210 as detailed in the IEEE 802.15.4
   2083 * 2006 specification.
   2084 *
   2085 * Return: 0 or linux error code
   2086 */
   2087static int ca8210_set_hw_addr_filt(
   2088	struct ieee802154_hw            *hw,
   2089	struct ieee802154_hw_addr_filt  *filt,
   2090	unsigned long                    changed
   2091)
   2092{
   2093	u8 status = 0;
   2094	struct ca8210_priv *priv = hw->priv;
   2095
   2096	if (changed & IEEE802154_AFILT_PANID_CHANGED) {
   2097		status = mlme_set_request_sync(
   2098			MAC_PAN_ID,
   2099			0,
   2100			2,
   2101			&filt->pan_id, priv->spi
   2102		);
   2103		if (status) {
   2104			dev_err(
   2105				&priv->spi->dev,
   2106				"error setting pan id, MLME-SET.confirm status = %d",
   2107				status
   2108			);
   2109			return link_to_linux_err(status);
   2110		}
   2111	}
   2112	if (changed & IEEE802154_AFILT_SADDR_CHANGED) {
   2113		status = mlme_set_request_sync(
   2114			MAC_SHORT_ADDRESS,
   2115			0,
   2116			2,
   2117			&filt->short_addr, priv->spi
   2118		);
   2119		if (status) {
   2120			dev_err(
   2121				&priv->spi->dev,
   2122				"error setting short address, MLME-SET.confirm status = %d",
   2123				status
   2124			);
   2125			return link_to_linux_err(status);
   2126		}
   2127	}
   2128	if (changed & IEEE802154_AFILT_IEEEADDR_CHANGED) {
   2129		status = mlme_set_request_sync(
   2130			NS_IEEE_ADDRESS,
   2131			0,
   2132			8,
   2133			&filt->ieee_addr,
   2134			priv->spi
   2135		);
   2136		if (status) {
   2137			dev_err(
   2138				&priv->spi->dev,
   2139				"error setting ieee address, MLME-SET.confirm status = %d",
   2140				status
   2141			);
   2142			return link_to_linux_err(status);
   2143		}
   2144	}
   2145	/* TODO: Should use MLME_START to set coord bit? */
   2146	return 0;
   2147}
   2148
   2149/**
   2150 * ca8210_set_tx_power() - Sets the transmit power of the ca8210
   2151 * @hw:   ieee802154_hw of target ca8210
   2152 * @mbm:  Transmit power in mBm (dBm*100)
   2153 *
   2154 * Return: 0 or linux error code
   2155 */
   2156static int ca8210_set_tx_power(struct ieee802154_hw *hw, s32 mbm)
   2157{
   2158	struct ca8210_priv *priv = hw->priv;
   2159
   2160	mbm /= 100;
   2161	return link_to_linux_err(
   2162		mlme_set_request_sync(PHY_TRANSMIT_POWER, 0, 1, &mbm, priv->spi)
   2163	);
   2164}
   2165
   2166/**
   2167 * ca8210_set_cca_mode() - Sets the clear channel assessment mode of the ca8210
   2168 * @hw:   ieee802154_hw of target ca8210
   2169 * @cca:  CCA mode to set
   2170 *
   2171 * Return: 0 or linux error code
   2172 */
   2173static int ca8210_set_cca_mode(
   2174	struct ieee802154_hw       *hw,
   2175	const struct wpan_phy_cca  *cca
   2176)
   2177{
   2178	u8 status;
   2179	u8 cca_mode;
   2180	struct ca8210_priv *priv = hw->priv;
   2181
   2182	cca_mode = cca->mode & 3;
   2183	if (cca_mode == 3 && cca->opt == NL802154_CCA_OPT_ENERGY_CARRIER_OR) {
   2184		/* cca_mode 0 == CS OR ED, 3 == CS AND ED */
   2185		cca_mode = 0;
   2186	}
   2187	status = mlme_set_request_sync(
   2188		PHY_CCA_MODE,
   2189		0,
   2190		1,
   2191		&cca_mode,
   2192		priv->spi
   2193	);
   2194	if (status) {
   2195		dev_err(
   2196			&priv->spi->dev,
   2197			"error setting cca mode, MLME-SET.confirm status = %d",
   2198			status
   2199		);
   2200	}
   2201	return link_to_linux_err(status);
   2202}
   2203
   2204/**
   2205 * ca8210_set_cca_ed_level() - Sets the CCA ED level of the ca8210
   2206 * @hw:     ieee802154_hw of target ca8210
   2207 * @level:  ED level to set (in mbm)
   2208 *
   2209 * Sets the minimum threshold of measured energy above which the ca8210 will
   2210 * back off and retry a transmission.
   2211 *
   2212 * Return: 0 or linux error code
   2213 */
   2214static int ca8210_set_cca_ed_level(struct ieee802154_hw *hw, s32 level)
   2215{
   2216	u8 status;
   2217	u8 ed_threshold = (level / 100) * 2 + 256;
   2218	struct ca8210_priv *priv = hw->priv;
   2219
   2220	status = hwme_set_request_sync(
   2221		HWME_EDTHRESHOLD,
   2222		1,
   2223		&ed_threshold,
   2224		priv->spi
   2225	);
   2226	if (status) {
   2227		dev_err(
   2228			&priv->spi->dev,
   2229			"error setting ed threshold, HWME-SET.confirm status = %d",
   2230			status
   2231		);
   2232	}
   2233	return link_to_linux_err(status);
   2234}
   2235
   2236/**
   2237 * ca8210_set_csma_params() - Sets the CSMA parameters of the ca8210
   2238 * @hw:       ieee802154_hw of target ca8210
   2239 * @min_be:   Minimum backoff exponent when backing off a transmission
   2240 * @max_be:   Maximum backoff exponent when backing off a transmission
   2241 * @retries:  Number of times to retry after backing off
   2242 *
   2243 * Return: 0 or linux error code
   2244 */
   2245static int ca8210_set_csma_params(
   2246	struct ieee802154_hw  *hw,
   2247	u8                     min_be,
   2248	u8                     max_be,
   2249	u8                     retries
   2250)
   2251{
   2252	u8 status;
   2253	struct ca8210_priv *priv = hw->priv;
   2254
   2255	status = mlme_set_request_sync(MAC_MIN_BE, 0, 1, &min_be, priv->spi);
   2256	if (status) {
   2257		dev_err(
   2258			&priv->spi->dev,
   2259			"error setting min be, MLME-SET.confirm status = %d",
   2260			status
   2261		);
   2262		return link_to_linux_err(status);
   2263	}
   2264	status = mlme_set_request_sync(MAC_MAX_BE, 0, 1, &max_be, priv->spi);
   2265	if (status) {
   2266		dev_err(
   2267			&priv->spi->dev,
   2268			"error setting max be, MLME-SET.confirm status = %d",
   2269			status
   2270		);
   2271		return link_to_linux_err(status);
   2272	}
   2273	status = mlme_set_request_sync(
   2274		MAC_MAX_CSMA_BACKOFFS,
   2275		0,
   2276		1,
   2277		&retries,
   2278		priv->spi
   2279	);
   2280	if (status) {
   2281		dev_err(
   2282			&priv->spi->dev,
   2283			"error setting max csma backoffs, MLME-SET.confirm status = %d",
   2284			status
   2285		);
   2286	}
   2287	return link_to_linux_err(status);
   2288}
   2289
   2290/**
   2291 * ca8210_set_frame_retries() - Sets the maximum frame retries of the ca8210
   2292 * @hw:       ieee802154_hw of target ca8210
   2293 * @retries:  Number of retries
   2294 *
   2295 * Sets the number of times to retry a transmission if no acknowledgment was
   2296 * was received from the other end when one was requested.
   2297 *
   2298 * Return: 0 or linux error code
   2299 */
   2300static int ca8210_set_frame_retries(struct ieee802154_hw *hw, s8 retries)
   2301{
   2302	u8 status;
   2303	struct ca8210_priv *priv = hw->priv;
   2304
   2305	status = mlme_set_request_sync(
   2306		MAC_MAX_FRAME_RETRIES,
   2307		0,
   2308		1,
   2309		&retries,
   2310		priv->spi
   2311	);
   2312	if (status) {
   2313		dev_err(
   2314			&priv->spi->dev,
   2315			"error setting frame retries, MLME-SET.confirm status = %d",
   2316			status
   2317		);
   2318	}
   2319	return link_to_linux_err(status);
   2320}
   2321
   2322static int ca8210_set_promiscuous_mode(struct ieee802154_hw *hw, const bool on)
   2323{
   2324	u8 status;
   2325	struct ca8210_priv *priv = hw->priv;
   2326
   2327	status = mlme_set_request_sync(
   2328		MAC_PROMISCUOUS_MODE,
   2329		0,
   2330		1,
   2331		(const void *)&on,
   2332		priv->spi
   2333	);
   2334	if (status) {
   2335		dev_err(
   2336			&priv->spi->dev,
   2337			"error setting promiscuous mode, MLME-SET.confirm status = %d",
   2338			status
   2339		);
   2340	} else {
   2341		priv->promiscuous = on;
   2342	}
   2343	return link_to_linux_err(status);
   2344}
   2345
   2346static const struct ieee802154_ops ca8210_phy_ops = {
   2347	.start = ca8210_start,
   2348	.stop = ca8210_stop,
   2349	.xmit_async = ca8210_xmit_async,
   2350	.ed = ca8210_get_ed,
   2351	.set_channel = ca8210_set_channel,
   2352	.set_hw_addr_filt = ca8210_set_hw_addr_filt,
   2353	.set_txpower = ca8210_set_tx_power,
   2354	.set_cca_mode = ca8210_set_cca_mode,
   2355	.set_cca_ed_level = ca8210_set_cca_ed_level,
   2356	.set_csma_params = ca8210_set_csma_params,
   2357	.set_frame_retries = ca8210_set_frame_retries,
   2358	.set_promiscuous_mode = ca8210_set_promiscuous_mode
   2359};
   2360
   2361/* Test/EVBME Interface */
   2362
   2363/**
   2364 * ca8210_test_int_open() - Opens the test interface to the userspace
   2365 * @inodp:  inode representation of file interface
   2366 * @filp:   file interface
   2367 *
   2368 * Return: 0 or linux error code
   2369 */
   2370static int ca8210_test_int_open(struct inode *inodp, struct file *filp)
   2371{
   2372	struct ca8210_priv *priv = inodp->i_private;
   2373
   2374	filp->private_data = priv;
   2375	return 0;
   2376}
   2377
   2378/**
   2379 * ca8210_test_check_upstream() - Checks a command received from the upstream
   2380 *                                testing interface for required action
   2381 * @buf:        Buffer containing command to check
   2382 * @device_ref: Nondescript pointer to target device
   2383 *
   2384 * Return: 0 or linux error code
   2385 */
   2386static int ca8210_test_check_upstream(u8 *buf, void *device_ref)
   2387{
   2388	int ret;
   2389	u8 response[CA8210_SPI_BUF_SIZE];
   2390
   2391	if (buf[0] == SPI_MLME_SET_REQUEST) {
   2392		ret = tdme_checkpibattribute(buf[2], buf[4], buf + 5);
   2393		if (ret) {
   2394			response[0]  = SPI_MLME_SET_CONFIRM;
   2395			response[1] = 3;
   2396			response[2] = IEEE802154_INVALID_PARAMETER;
   2397			response[3] = buf[2];
   2398			response[4] = buf[3];
   2399			if (cascoda_api_upstream)
   2400				cascoda_api_upstream(response, 5, device_ref);
   2401			return ret;
   2402		}
   2403	}
   2404	if (buf[0] == SPI_MLME_ASSOCIATE_REQUEST) {
   2405		return tdme_channelinit(buf[2], device_ref);
   2406	} else if (buf[0] == SPI_MLME_START_REQUEST) {
   2407		return tdme_channelinit(buf[4], device_ref);
   2408	} else if (
   2409		(buf[0] == SPI_MLME_SET_REQUEST) &&
   2410		(buf[2] == PHY_CURRENT_CHANNEL)
   2411	) {
   2412		return tdme_channelinit(buf[5], device_ref);
   2413	} else if (
   2414		(buf[0] == SPI_TDME_SET_REQUEST) &&
   2415		(buf[2] == TDME_CHANNEL)
   2416	) {
   2417		return tdme_channelinit(buf[4], device_ref);
   2418	} else if (
   2419		(CA8210_MAC_WORKAROUNDS) &&
   2420		(buf[0] == SPI_MLME_RESET_REQUEST) &&
   2421		(buf[2] == 1)
   2422	) {
   2423		/* reset COORD Bit for Channel Filtering as Coordinator */
   2424		return tdme_setsfr_request_sync(
   2425			0,
   2426			CA8210_SFR_MACCON,
   2427			0,
   2428			device_ref
   2429		);
   2430	}
   2431	return 0;
   2432} /* End of EVBMECheckSerialCommand() */
   2433
   2434/**
   2435 * ca8210_test_int_user_write() - Called by a process in userspace to send a
   2436 *                                message to the ca8210 drivers
   2437 * @filp:    file interface
   2438 * @in_buf:  Buffer containing message to write
   2439 * @len:     length of message
   2440 * @off:     file offset
   2441 *
   2442 * Return: 0 or linux error code
   2443 */
   2444static ssize_t ca8210_test_int_user_write(
   2445	struct file        *filp,
   2446	const char __user  *in_buf,
   2447	size_t              len,
   2448	loff_t             *off
   2449)
   2450{
   2451	int ret;
   2452	struct ca8210_priv *priv = filp->private_data;
   2453	u8 command[CA8210_SPI_BUF_SIZE];
   2454
   2455	memset(command, SPI_IDLE, 6);
   2456	if (len > CA8210_SPI_BUF_SIZE || len < 2) {
   2457		dev_warn(
   2458			&priv->spi->dev,
   2459			"userspace requested erroneous write length (%zu)\n",
   2460			len
   2461		);
   2462		return -EBADE;
   2463	}
   2464
   2465	ret = copy_from_user(command, in_buf, len);
   2466	if (ret) {
   2467		dev_err(
   2468			&priv->spi->dev,
   2469			"%d bytes could not be copied from userspace\n",
   2470			ret
   2471		);
   2472		return -EIO;
   2473	}
   2474	if (len != command[1] + 2) {
   2475		dev_err(
   2476			&priv->spi->dev,
   2477			"write len does not match packet length field\n"
   2478		);
   2479		return -EBADE;
   2480	}
   2481
   2482	ret = ca8210_test_check_upstream(command, priv->spi);
   2483	if (ret == 0) {
   2484		ret = ca8210_spi_exchange(
   2485			command,
   2486			command[1] + 2,
   2487			NULL,
   2488			priv->spi
   2489		);
   2490		if (ret < 0) {
   2491			/* effectively 0 bytes were written successfully */
   2492			dev_err(
   2493				&priv->spi->dev,
   2494				"spi exchange failed\n"
   2495			);
   2496			return ret;
   2497		}
   2498		if (command[0] & SPI_SYN)
   2499			priv->sync_down++;
   2500	}
   2501
   2502	return len;
   2503}
   2504
   2505/**
   2506 * ca8210_test_int_user_read() - Called by a process in userspace to read a
   2507 *                               message from the ca8210 drivers
   2508 * @filp:  file interface
   2509 * @buf:   Buffer to write message to
   2510 * @len:   length of message to read (ignored)
   2511 * @offp:  file offset
   2512 *
   2513 * If the O_NONBLOCK flag was set when opening the file then this function will
   2514 * not block, i.e. it will return if the fifo is empty. Otherwise the function
   2515 * will block, i.e. wait until new data arrives.
   2516 *
   2517 * Return: number of bytes read
   2518 */
   2519static ssize_t ca8210_test_int_user_read(
   2520	struct file  *filp,
   2521	char __user  *buf,
   2522	size_t        len,
   2523	loff_t       *offp
   2524)
   2525{
   2526	int i, cmdlen;
   2527	struct ca8210_priv *priv = filp->private_data;
   2528	unsigned char *fifo_buffer;
   2529	unsigned long bytes_not_copied;
   2530
   2531	if (filp->f_flags & O_NONBLOCK) {
   2532		/* Non-blocking mode */
   2533		if (kfifo_is_empty(&priv->test.up_fifo))
   2534			return 0;
   2535	} else {
   2536		/* Blocking mode */
   2537		wait_event_interruptible(
   2538			priv->test.readq,
   2539			!kfifo_is_empty(&priv->test.up_fifo)
   2540		);
   2541	}
   2542
   2543	if (kfifo_out(&priv->test.up_fifo, &fifo_buffer, 4) != 4) {
   2544		dev_err(
   2545			&priv->spi->dev,
   2546			"test_interface: Wrong number of elements popped from upstream fifo\n"
   2547		);
   2548		return 0;
   2549	}
   2550	cmdlen = fifo_buffer[1];
   2551	bytes_not_copied = cmdlen + 2;
   2552
   2553	bytes_not_copied = copy_to_user(buf, fifo_buffer, bytes_not_copied);
   2554	if (bytes_not_copied > 0) {
   2555		dev_err(
   2556			&priv->spi->dev,
   2557			"%lu bytes could not be copied to user space!\n",
   2558			bytes_not_copied
   2559		);
   2560	}
   2561
   2562	dev_dbg(&priv->spi->dev, "test_interface: Cmd len = %d\n", cmdlen);
   2563
   2564	dev_dbg(&priv->spi->dev, "test_interface: Read\n");
   2565	for (i = 0; i < cmdlen + 2; i++)
   2566		dev_dbg(&priv->spi->dev, "%#03x\n", fifo_buffer[i]);
   2567
   2568	kfree(fifo_buffer);
   2569
   2570	return cmdlen + 2;
   2571}
   2572
   2573/**
   2574 * ca8210_test_int_ioctl() - Called by a process in userspace to enact an
   2575 *                           arbitrary action
   2576 * @filp:        file interface
   2577 * @ioctl_num:   which action to enact
   2578 * @ioctl_param: arbitrary parameter for the action
   2579 *
   2580 * Return: status
   2581 */
   2582static long ca8210_test_int_ioctl(
   2583	struct file *filp,
   2584	unsigned int ioctl_num,
   2585	unsigned long ioctl_param
   2586)
   2587{
   2588	struct ca8210_priv *priv = filp->private_data;
   2589
   2590	switch (ioctl_num) {
   2591	case CA8210_IOCTL_HARD_RESET:
   2592		ca8210_reset_send(priv->spi, ioctl_param);
   2593		break;
   2594	default:
   2595		break;
   2596	}
   2597	return 0;
   2598}
   2599
   2600/**
   2601 * ca8210_test_int_poll() - Called by a process in userspace to determine which
   2602 *                          actions are currently possible for the file
   2603 * @filp:   file interface
   2604 * @ptable: poll table
   2605 *
   2606 * Return: set of poll return flags
   2607 */
   2608static __poll_t ca8210_test_int_poll(
   2609	struct file *filp,
   2610	struct poll_table_struct *ptable
   2611)
   2612{
   2613	__poll_t return_flags = 0;
   2614	struct ca8210_priv *priv = filp->private_data;
   2615
   2616	poll_wait(filp, &priv->test.readq, ptable);
   2617	if (!kfifo_is_empty(&priv->test.up_fifo))
   2618		return_flags |= (EPOLLIN | EPOLLRDNORM);
   2619	if (wait_event_interruptible(
   2620		priv->test.readq,
   2621		!kfifo_is_empty(&priv->test.up_fifo))) {
   2622		return EPOLLERR;
   2623	}
   2624	return return_flags;
   2625}
   2626
   2627static const struct file_operations test_int_fops = {
   2628	.read =           ca8210_test_int_user_read,
   2629	.write =          ca8210_test_int_user_write,
   2630	.open =           ca8210_test_int_open,
   2631	.release =        NULL,
   2632	.unlocked_ioctl = ca8210_test_int_ioctl,
   2633	.poll =           ca8210_test_int_poll
   2634};
   2635
   2636/* Init/Deinit */
   2637
   2638/**
   2639 * ca8210_get_platform_data() - Populate a ca8210_platform_data object
   2640 * @spi_device:  Pointer to ca8210 spi device object to get data for
   2641 * @pdata:       Pointer to ca8210_platform_data object to populate
   2642 *
   2643 * Return: 0 or linux error code
   2644 */
   2645static int ca8210_get_platform_data(
   2646	struct spi_device *spi_device,
   2647	struct ca8210_platform_data *pdata
   2648)
   2649{
   2650	int ret = 0;
   2651
   2652	if (!spi_device->dev.of_node)
   2653		return -EINVAL;
   2654
   2655	pdata->extclockenable = of_property_read_bool(
   2656		spi_device->dev.of_node,
   2657		"extclock-enable"
   2658	);
   2659	if (pdata->extclockenable) {
   2660		ret = of_property_read_u32(
   2661			spi_device->dev.of_node,
   2662			"extclock-freq",
   2663			&pdata->extclockfreq
   2664		);
   2665		if (ret < 0)
   2666			return ret;
   2667
   2668		ret = of_property_read_u32(
   2669			spi_device->dev.of_node,
   2670			"extclock-gpio",
   2671			&pdata->extclockgpio
   2672		);
   2673	}
   2674
   2675	return ret;
   2676}
   2677
   2678/**
   2679 * ca8210_config_extern_clk() - Configure the external clock provided by the
   2680 *                              ca8210
   2681 * @pdata:  Pointer to ca8210_platform_data containing clock parameters
   2682 * @spi:    Pointer to target ca8210 spi device
   2683 * @on:	    True to turn the clock on, false to turn off
   2684 *
   2685 * The external clock is configured with a frequency and output pin taken from
   2686 * the platform data.
   2687 *
   2688 * Return: 0 or linux error code
   2689 */
   2690static int ca8210_config_extern_clk(
   2691	struct ca8210_platform_data *pdata,
   2692	struct spi_device *spi,
   2693	bool on
   2694)
   2695{
   2696	u8 clkparam[2];
   2697
   2698	if (on) {
   2699		dev_info(&spi->dev, "Switching external clock on\n");
   2700		switch (pdata->extclockfreq) {
   2701		case SIXTEEN_MHZ:
   2702			clkparam[0] = 1;
   2703			break;
   2704		case EIGHT_MHZ:
   2705			clkparam[0] = 2;
   2706			break;
   2707		case FOUR_MHZ:
   2708			clkparam[0] = 3;
   2709			break;
   2710		case TWO_MHZ:
   2711			clkparam[0] = 4;
   2712			break;
   2713		case ONE_MHZ:
   2714			clkparam[0] = 5;
   2715			break;
   2716		default:
   2717			dev_crit(&spi->dev, "Invalid extclock-freq\n");
   2718			return -EINVAL;
   2719		}
   2720		clkparam[1] = pdata->extclockgpio;
   2721	} else {
   2722		dev_info(&spi->dev, "Switching external clock off\n");
   2723		clkparam[0] = 0; /* off */
   2724		clkparam[1] = 0;
   2725	}
   2726	return link_to_linux_err(
   2727		hwme_set_request_sync(HWME_SYSCLKOUT, 2, clkparam, spi)
   2728	);
   2729}
   2730
   2731/**
   2732 * ca8210_register_ext_clock() - Register ca8210's external clock with kernel
   2733 * @spi:  Pointer to target ca8210 spi device
   2734 *
   2735 * Return: 0 or linux error code
   2736 */
   2737static int ca8210_register_ext_clock(struct spi_device *spi)
   2738{
   2739	struct device_node *np = spi->dev.of_node;
   2740	struct ca8210_priv *priv = spi_get_drvdata(spi);
   2741	struct ca8210_platform_data *pdata = spi->dev.platform_data;
   2742	int ret = 0;
   2743
   2744	if (!np)
   2745		return -EFAULT;
   2746
   2747	priv->clk = clk_register_fixed_rate(
   2748		&spi->dev,
   2749		np->name,
   2750		NULL,
   2751		0,
   2752		pdata->extclockfreq
   2753	);
   2754
   2755	if (IS_ERR(priv->clk)) {
   2756		dev_crit(&spi->dev, "Failed to register external clk\n");
   2757		return PTR_ERR(priv->clk);
   2758	}
   2759	ret = of_clk_add_provider(np, of_clk_src_simple_get, priv->clk);
   2760	if (ret) {
   2761		clk_unregister(priv->clk);
   2762		dev_crit(
   2763			&spi->dev,
   2764			"Failed to register external clock as clock provider\n"
   2765		);
   2766	} else {
   2767		dev_info(&spi->dev, "External clock set as clock provider\n");
   2768	}
   2769
   2770	return ret;
   2771}
   2772
   2773/**
   2774 * ca8210_unregister_ext_clock() - Unregister ca8210's external clock with
   2775 *                                 kernel
   2776 * @spi:  Pointer to target ca8210 spi device
   2777 */
   2778static void ca8210_unregister_ext_clock(struct spi_device *spi)
   2779{
   2780	struct ca8210_priv *priv = spi_get_drvdata(spi);
   2781
   2782	if (!priv->clk)
   2783		return
   2784
   2785	of_clk_del_provider(spi->dev.of_node);
   2786	clk_unregister(priv->clk);
   2787	dev_info(&spi->dev, "External clock unregistered\n");
   2788}
   2789
   2790/**
   2791 * ca8210_reset_init() - Initialise the reset input to the ca8210
   2792 * @spi:  Pointer to target ca8210 spi device
   2793 *
   2794 * Return: 0 or linux error code
   2795 */
   2796static int ca8210_reset_init(struct spi_device *spi)
   2797{
   2798	int ret;
   2799	struct ca8210_platform_data *pdata = spi->dev.platform_data;
   2800
   2801	pdata->gpio_reset = of_get_named_gpio(
   2802		spi->dev.of_node,
   2803		"reset-gpio",
   2804		0
   2805	);
   2806
   2807	ret = gpio_direction_output(pdata->gpio_reset, 1);
   2808	if (ret < 0) {
   2809		dev_crit(
   2810			&spi->dev,
   2811			"Reset GPIO %d did not set to output mode\n",
   2812			pdata->gpio_reset
   2813		);
   2814	}
   2815
   2816	return ret;
   2817}
   2818
   2819/**
   2820 * ca8210_interrupt_init() - Initialise the irq output from the ca8210
   2821 * @spi:  Pointer to target ca8210 spi device
   2822 *
   2823 * Return: 0 or linux error code
   2824 */
   2825static int ca8210_interrupt_init(struct spi_device *spi)
   2826{
   2827	int ret;
   2828	struct ca8210_platform_data *pdata = spi->dev.platform_data;
   2829
   2830	pdata->gpio_irq = of_get_named_gpio(
   2831		spi->dev.of_node,
   2832		"irq-gpio",
   2833		0
   2834	);
   2835
   2836	pdata->irq_id = gpio_to_irq(pdata->gpio_irq);
   2837	if (pdata->irq_id < 0) {
   2838		dev_crit(
   2839			&spi->dev,
   2840			"Could not get irq for gpio pin %d\n",
   2841			pdata->gpio_irq
   2842		);
   2843		gpio_free(pdata->gpio_irq);
   2844		return pdata->irq_id;
   2845	}
   2846
   2847	ret = request_irq(
   2848		pdata->irq_id,
   2849		ca8210_interrupt_handler,
   2850		IRQF_TRIGGER_FALLING,
   2851		"ca8210-irq",
   2852		spi_get_drvdata(spi)
   2853	);
   2854	if (ret) {
   2855		dev_crit(&spi->dev, "request_irq %d failed\n", pdata->irq_id);
   2856		gpio_unexport(pdata->gpio_irq);
   2857		gpio_free(pdata->gpio_irq);
   2858	}
   2859
   2860	return ret;
   2861}
   2862
   2863/**
   2864 * ca8210_dev_com_init() - Initialise the spi communication component
   2865 * @priv:  Pointer to private data structure
   2866 *
   2867 * Return: 0 or linux error code
   2868 */
   2869static int ca8210_dev_com_init(struct ca8210_priv *priv)
   2870{
   2871	priv->mlme_workqueue = alloc_ordered_workqueue(
   2872		"MLME work queue",
   2873		WQ_UNBOUND
   2874	);
   2875	if (!priv->mlme_workqueue) {
   2876		dev_crit(&priv->spi->dev, "alloc of mlme_workqueue failed!\n");
   2877		return -ENOMEM;
   2878	}
   2879
   2880	priv->irq_workqueue = alloc_ordered_workqueue(
   2881		"ca8210 irq worker",
   2882		WQ_UNBOUND
   2883	);
   2884	if (!priv->irq_workqueue) {
   2885		dev_crit(&priv->spi->dev, "alloc of irq_workqueue failed!\n");
   2886		destroy_workqueue(priv->mlme_workqueue);
   2887		return -ENOMEM;
   2888	}
   2889
   2890	return 0;
   2891}
   2892
   2893/**
   2894 * ca8210_dev_com_clear() - Deinitialise the spi communication component
   2895 * @priv:  Pointer to private data structure
   2896 */
   2897static void ca8210_dev_com_clear(struct ca8210_priv *priv)
   2898{
   2899	destroy_workqueue(priv->mlme_workqueue);
   2900	destroy_workqueue(priv->irq_workqueue);
   2901}
   2902
   2903#define CA8210_MAX_TX_POWERS (9)
   2904static const s32 ca8210_tx_powers[CA8210_MAX_TX_POWERS] = {
   2905	800, 700, 600, 500, 400, 300, 200, 100, 0
   2906};
   2907
   2908#define CA8210_MAX_ED_LEVELS (21)
   2909static const s32 ca8210_ed_levels[CA8210_MAX_ED_LEVELS] = {
   2910	-10300, -10250, -10200, -10150, -10100, -10050, -10000, -9950, -9900,
   2911	-9850, -9800, -9750, -9700, -9650, -9600, -9550, -9500, -9450, -9400,
   2912	-9350, -9300
   2913};
   2914
   2915/**
   2916 * ca8210_hw_setup() - Populate the ieee802154_hw phy attributes with the
   2917 *                     ca8210's defaults
   2918 * @ca8210_hw:  Pointer to ieee802154_hw to populate
   2919 */
   2920static void ca8210_hw_setup(struct ieee802154_hw *ca8210_hw)
   2921{
   2922	/* Support channels 11-26 */
   2923	ca8210_hw->phy->supported.channels[0] = CA8210_VALID_CHANNELS;
   2924	ca8210_hw->phy->supported.tx_powers_size = CA8210_MAX_TX_POWERS;
   2925	ca8210_hw->phy->supported.tx_powers = ca8210_tx_powers;
   2926	ca8210_hw->phy->supported.cca_ed_levels_size = CA8210_MAX_ED_LEVELS;
   2927	ca8210_hw->phy->supported.cca_ed_levels = ca8210_ed_levels;
   2928	ca8210_hw->phy->current_channel = 18;
   2929	ca8210_hw->phy->current_page = 0;
   2930	ca8210_hw->phy->transmit_power = 800;
   2931	ca8210_hw->phy->cca.mode = NL802154_CCA_ENERGY_CARRIER;
   2932	ca8210_hw->phy->cca.opt = NL802154_CCA_OPT_ENERGY_CARRIER_AND;
   2933	ca8210_hw->phy->cca_ed_level = -9800;
   2934	ca8210_hw->phy->symbol_duration = 16;
   2935	ca8210_hw->phy->lifs_period = 40 * ca8210_hw->phy->symbol_duration;
   2936	ca8210_hw->phy->sifs_period = 12 * ca8210_hw->phy->symbol_duration;
   2937	ca8210_hw->flags =
   2938		IEEE802154_HW_AFILT |
   2939		IEEE802154_HW_OMIT_CKSUM |
   2940		IEEE802154_HW_FRAME_RETRIES |
   2941		IEEE802154_HW_PROMISCUOUS |
   2942		IEEE802154_HW_CSMA_PARAMS;
   2943	ca8210_hw->phy->flags =
   2944		WPAN_PHY_FLAG_TXPOWER |
   2945		WPAN_PHY_FLAG_CCA_ED_LEVEL |
   2946		WPAN_PHY_FLAG_CCA_MODE;
   2947}
   2948
   2949/**
   2950 * ca8210_test_interface_init() - Initialise the test file interface
   2951 * @priv:  Pointer to private data structure
   2952 *
   2953 * Provided as an alternative to the standard linux network interface, the test
   2954 * interface exposes a file in the filesystem (ca8210_test) that allows
   2955 * 802.15.4 SAP Commands and Cascoda EVBME commands to be sent directly to
   2956 * the stack.
   2957 *
   2958 * Return: 0 or linux error code
   2959 */
   2960static int ca8210_test_interface_init(struct ca8210_priv *priv)
   2961{
   2962	struct ca8210_test *test = &priv->test;
   2963	char node_name[32];
   2964
   2965	snprintf(
   2966		node_name,
   2967		sizeof(node_name),
   2968		"ca8210@%d_%d",
   2969		priv->spi->master->bus_num,
   2970		priv->spi->chip_select
   2971	);
   2972
   2973	test->ca8210_dfs_spi_int = debugfs_create_file(
   2974		node_name,
   2975		0600, /* S_IRUSR | S_IWUSR */
   2976		NULL,
   2977		priv,
   2978		&test_int_fops
   2979	);
   2980
   2981	debugfs_create_symlink("ca8210", NULL, node_name);
   2982	init_waitqueue_head(&test->readq);
   2983	return kfifo_alloc(
   2984		&test->up_fifo,
   2985		CA8210_TEST_INT_FIFO_SIZE,
   2986		GFP_KERNEL
   2987	);
   2988}
   2989
   2990/**
   2991 * ca8210_test_interface_clear() - Deinitialise the test file interface
   2992 * @priv:  Pointer to private data structure
   2993 */
   2994static void ca8210_test_interface_clear(struct ca8210_priv *priv)
   2995{
   2996	struct ca8210_test *test = &priv->test;
   2997
   2998	debugfs_remove(test->ca8210_dfs_spi_int);
   2999	kfifo_free(&test->up_fifo);
   3000	dev_info(&priv->spi->dev, "Test interface removed\n");
   3001}
   3002
   3003/**
   3004 * ca8210_remove() - Shut down a ca8210 upon being disconnected
   3005 * @spi_device:  Pointer to spi device data structure
   3006 *
   3007 * Return: 0 or linux error code
   3008 */
   3009static void ca8210_remove(struct spi_device *spi_device)
   3010{
   3011	struct ca8210_priv *priv;
   3012	struct ca8210_platform_data *pdata;
   3013
   3014	dev_info(&spi_device->dev, "Removing ca8210\n");
   3015
   3016	pdata = spi_device->dev.platform_data;
   3017	if (pdata) {
   3018		if (pdata->extclockenable) {
   3019			ca8210_unregister_ext_clock(spi_device);
   3020			ca8210_config_extern_clk(pdata, spi_device, 0);
   3021		}
   3022		free_irq(pdata->irq_id, spi_device->dev.driver_data);
   3023		kfree(pdata);
   3024		spi_device->dev.platform_data = NULL;
   3025	}
   3026	/* get spi_device private data */
   3027	priv = spi_get_drvdata(spi_device);
   3028	if (priv) {
   3029		dev_info(
   3030			&spi_device->dev,
   3031			"sync_down = %d, sync_up = %d\n",
   3032			priv->sync_down,
   3033			priv->sync_up
   3034		);
   3035		ca8210_dev_com_clear(spi_device->dev.driver_data);
   3036		if (priv->hw) {
   3037			if (priv->hw_registered)
   3038				ieee802154_unregister_hw(priv->hw);
   3039			ieee802154_free_hw(priv->hw);
   3040			priv->hw = NULL;
   3041			dev_info(
   3042				&spi_device->dev,
   3043				"Unregistered & freed ieee802154_hw.\n"
   3044			);
   3045		}
   3046		if (IS_ENABLED(CONFIG_IEEE802154_CA8210_DEBUGFS))
   3047			ca8210_test_interface_clear(priv);
   3048	}
   3049}
   3050
   3051/**
   3052 * ca8210_probe() - Set up a connected ca8210 upon being detected by the system
   3053 * @spi_device:  Pointer to spi device data structure
   3054 *
   3055 * Return: 0 or linux error code
   3056 */
   3057static int ca8210_probe(struct spi_device *spi_device)
   3058{
   3059	struct ca8210_priv *priv;
   3060	struct ieee802154_hw *hw;
   3061	struct ca8210_platform_data *pdata;
   3062	int ret;
   3063
   3064	dev_info(&spi_device->dev, "Inserting ca8210\n");
   3065
   3066	/* allocate ieee802154_hw and private data */
   3067	hw = ieee802154_alloc_hw(sizeof(struct ca8210_priv), &ca8210_phy_ops);
   3068	if (!hw) {
   3069		dev_crit(&spi_device->dev, "ieee802154_alloc_hw failed\n");
   3070		ret = -ENOMEM;
   3071		goto error;
   3072	}
   3073
   3074	priv = hw->priv;
   3075	priv->hw = hw;
   3076	priv->spi = spi_device;
   3077	hw->parent = &spi_device->dev;
   3078	spin_lock_init(&priv->lock);
   3079	priv->async_tx_pending = false;
   3080	priv->hw_registered = false;
   3081	priv->sync_up = 0;
   3082	priv->sync_down = 0;
   3083	priv->promiscuous = false;
   3084	priv->retries = 0;
   3085	init_completion(&priv->ca8210_is_awake);
   3086	init_completion(&priv->spi_transfer_complete);
   3087	init_completion(&priv->sync_exchange_complete);
   3088	spi_set_drvdata(priv->spi, priv);
   3089	if (IS_ENABLED(CONFIG_IEEE802154_CA8210_DEBUGFS)) {
   3090		cascoda_api_upstream = ca8210_test_int_driver_write;
   3091		ca8210_test_interface_init(priv);
   3092	} else {
   3093		cascoda_api_upstream = NULL;
   3094	}
   3095	ca8210_hw_setup(hw);
   3096	ieee802154_random_extended_addr(&hw->phy->perm_extended_addr);
   3097
   3098	pdata = kmalloc(sizeof(*pdata), GFP_KERNEL);
   3099	if (!pdata) {
   3100		ret = -ENOMEM;
   3101		goto error;
   3102	}
   3103
   3104	priv->spi->dev.platform_data = pdata;
   3105	ret = ca8210_get_platform_data(priv->spi, pdata);
   3106	if (ret) {
   3107		dev_crit(&spi_device->dev, "ca8210_get_platform_data failed\n");
   3108		goto error;
   3109	}
   3110
   3111	ret = ca8210_dev_com_init(priv);
   3112	if (ret) {
   3113		dev_crit(&spi_device->dev, "ca8210_dev_com_init failed\n");
   3114		goto error;
   3115	}
   3116	ret = ca8210_reset_init(priv->spi);
   3117	if (ret) {
   3118		dev_crit(&spi_device->dev, "ca8210_reset_init failed\n");
   3119		goto error;
   3120	}
   3121
   3122	ret = ca8210_interrupt_init(priv->spi);
   3123	if (ret) {
   3124		dev_crit(&spi_device->dev, "ca8210_interrupt_init failed\n");
   3125		goto error;
   3126	}
   3127
   3128	msleep(100);
   3129
   3130	ca8210_reset_send(priv->spi, 1);
   3131
   3132	ret = tdme_chipinit(priv->spi);
   3133	if (ret) {
   3134		dev_crit(&spi_device->dev, "tdme_chipinit failed\n");
   3135		goto error;
   3136	}
   3137
   3138	if (pdata->extclockenable) {
   3139		ret = ca8210_config_extern_clk(pdata, priv->spi, 1);
   3140		if (ret) {
   3141			dev_crit(
   3142				&spi_device->dev,
   3143				"ca8210_config_extern_clk failed\n"
   3144			);
   3145			goto error;
   3146		}
   3147		ret = ca8210_register_ext_clock(priv->spi);
   3148		if (ret) {
   3149			dev_crit(
   3150				&spi_device->dev,
   3151				"ca8210_register_ext_clock failed\n"
   3152			);
   3153			goto error;
   3154		}
   3155	}
   3156
   3157	ret = ieee802154_register_hw(hw);
   3158	if (ret) {
   3159		dev_crit(&spi_device->dev, "ieee802154_register_hw failed\n");
   3160		goto error;
   3161	}
   3162	priv->hw_registered = true;
   3163
   3164	return 0;
   3165error:
   3166	msleep(100); /* wait for pending spi transfers to complete */
   3167	ca8210_remove(spi_device);
   3168	return link_to_linux_err(ret);
   3169}
   3170
   3171static const struct of_device_id ca8210_of_ids[] = {
   3172	{.compatible = "cascoda,ca8210", },
   3173	{},
   3174};
   3175MODULE_DEVICE_TABLE(of, ca8210_of_ids);
   3176
   3177static struct spi_driver ca8210_spi_driver = {
   3178	.driver = {
   3179		.name =                 DRIVER_NAME,
   3180		.owner =                THIS_MODULE,
   3181		.of_match_table =       of_match_ptr(ca8210_of_ids),
   3182	},
   3183	.probe  =                       ca8210_probe,
   3184	.remove =                       ca8210_remove
   3185};
   3186
   3187module_spi_driver(ca8210_spi_driver);
   3188
   3189MODULE_AUTHOR("Harry Morris <h.morris@cascoda.com>");
   3190MODULE_DESCRIPTION("CA-8210 SoftMAC driver");
   3191MODULE_LICENSE("Dual BSD/GPL");
   3192MODULE_VERSION("1.0");