root/drivers/net/ethernet/qualcomm/qca_7k_common.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. qcafrm_create_header
  2. qcafrm_create_footer
  3. qcafrm_fsm_decode

   1 /*
   2  *   Copyright (c) 2011, 2012, Atheros Communications Inc.
   3  *   Copyright (c) 2014, I2SE GmbH
   4  *
   5  *   Permission to use, copy, modify, and/or distribute this software
   6  *   for any purpose with or without fee is hereby granted, provided
   7  *   that the above copyright notice and this permission notice appear
   8  *   in all copies.
   9  *
  10  *   THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
  11  *   WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
  12  *   WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
  13  *   THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
  14  *   CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  15  *   LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
  16  *   NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  17  *   CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  18  */
  19 
  20 /*   Atheros ethernet framing. Every Ethernet frame is surrounded
  21  *   by an atheros frame while transmitted over a serial channel;
  22  */
  23 
  24 #include <linux/init.h>
  25 #include <linux/kernel.h>
  26 #include <linux/module.h>
  27 
  28 #include "qca_7k_common.h"
  29 
  30 u16
  31 qcafrm_create_header(u8 *buf, u16 length)
  32 {
  33         __le16 len;
  34 
  35         if (!buf)
  36                 return 0;
  37 
  38         len = cpu_to_le16(length);
  39 
  40         buf[0] = 0xAA;
  41         buf[1] = 0xAA;
  42         buf[2] = 0xAA;
  43         buf[3] = 0xAA;
  44         buf[4] = len & 0xff;
  45         buf[5] = (len >> 8) & 0xff;
  46         buf[6] = 0;
  47         buf[7] = 0;
  48 
  49         return QCAFRM_HEADER_LEN;
  50 }
  51 EXPORT_SYMBOL_GPL(qcafrm_create_header);
  52 
  53 u16
  54 qcafrm_create_footer(u8 *buf)
  55 {
  56         if (!buf)
  57                 return 0;
  58 
  59         buf[0] = 0x55;
  60         buf[1] = 0x55;
  61         return QCAFRM_FOOTER_LEN;
  62 }
  63 EXPORT_SYMBOL_GPL(qcafrm_create_footer);
  64 
  65 /*   Gather received bytes and try to extract a full ethernet frame by
  66  *   following a simple state machine.
  67  *
  68  * Return:   QCAFRM_GATHER       No ethernet frame fully received yet.
  69  *           QCAFRM_NOHEAD       Header expected but not found.
  70  *           QCAFRM_INVLEN       Atheros frame length is invalid
  71  *           QCAFRM_NOTAIL       Footer expected but not found.
  72  *           > 0                 Number of byte in the fully received
  73  *                               Ethernet frame
  74  */
  75 
  76 s32
  77 qcafrm_fsm_decode(struct qcafrm_handle *handle, u8 *buf, u16 buf_len, u8 recv_byte)
  78 {
  79         s32 ret = QCAFRM_GATHER;
  80         u16 len;
  81 
  82         switch (handle->state) {
  83         case QCAFRM_HW_LEN0:
  84         case QCAFRM_HW_LEN1:
  85                 /* by default, just go to next state */
  86                 handle->state--;
  87 
  88                 if (recv_byte != 0x00) {
  89                         /* first two bytes of length must be 0 */
  90                         handle->state = handle->init;
  91                 }
  92                 break;
  93         case QCAFRM_HW_LEN2:
  94         case QCAFRM_HW_LEN3:
  95                 handle->state--;
  96                 break;
  97         /* 4 bytes header pattern */
  98         case QCAFRM_WAIT_AA1:
  99         case QCAFRM_WAIT_AA2:
 100         case QCAFRM_WAIT_AA3:
 101         case QCAFRM_WAIT_AA4:
 102                 if (recv_byte != 0xAA) {
 103                         ret = QCAFRM_NOHEAD;
 104                         handle->state = handle->init;
 105                 } else {
 106                         handle->state--;
 107                 }
 108                 break;
 109                 /* 2 bytes length. */
 110                 /* Borrow offset field to hold length for now. */
 111         case QCAFRM_WAIT_LEN_BYTE0:
 112                 handle->offset = recv_byte;
 113                 handle->state = QCAFRM_WAIT_LEN_BYTE1;
 114                 break;
 115         case QCAFRM_WAIT_LEN_BYTE1:
 116                 handle->offset = handle->offset | (recv_byte << 8);
 117                 handle->state = QCAFRM_WAIT_RSVD_BYTE1;
 118                 break;
 119         case QCAFRM_WAIT_RSVD_BYTE1:
 120                 handle->state = QCAFRM_WAIT_RSVD_BYTE2;
 121                 break;
 122         case QCAFRM_WAIT_RSVD_BYTE2:
 123                 len = handle->offset;
 124                 if (len > buf_len || len < QCAFRM_MIN_LEN) {
 125                         ret = QCAFRM_INVLEN;
 126                         handle->state = handle->init;
 127                 } else {
 128                         handle->state = (enum qcafrm_state)(len + 1);
 129                         /* Remaining number of bytes. */
 130                         handle->offset = 0;
 131                 }
 132                 break;
 133         default:
 134                 /* Receiving Ethernet frame itself. */
 135                 buf[handle->offset] = recv_byte;
 136                 handle->offset++;
 137                 handle->state--;
 138                 break;
 139         case QCAFRM_WAIT_551:
 140                 if (recv_byte != 0x55) {
 141                         ret = QCAFRM_NOTAIL;
 142                         handle->state = handle->init;
 143                 } else {
 144                         handle->state = QCAFRM_WAIT_552;
 145                 }
 146                 break;
 147         case QCAFRM_WAIT_552:
 148                 if (recv_byte != 0x55) {
 149                         ret = QCAFRM_NOTAIL;
 150                         handle->state = handle->init;
 151                 } else {
 152                         ret = handle->offset;
 153                         /* Frame is fully received. */
 154                         handle->state = handle->init;
 155                 }
 156                 break;
 157         }
 158 
 159         return ret;
 160 }
 161 EXPORT_SYMBOL_GPL(qcafrm_fsm_decode);
 162 
 163 MODULE_DESCRIPTION("Qualcomm Atheros QCA7000 common");
 164 MODULE_AUTHOR("Qualcomm Atheros Communications");
 165 MODULE_AUTHOR("Stefan Wahren <stefan.wahren@i2se.com>");
 166 MODULE_LICENSE("Dual BSD/GPL");

/* [<][>][^][v][top][bottom][index][help] */