154 lines · c
1// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause2/*3 * Copyright (c) 2011, 2012, Atheros Communications Inc.4 * Copyright (c) 2014, I2SE GmbH5 */6 7/* Atheros ethernet framing. Every Ethernet frame is surrounded8 * by an atheros frame while transmitted over a serial channel;9 */10 11#include <linux/init.h>12#include <linux/kernel.h>13#include <linux/module.h>14 15#include "qca_7k_common.h"16 17u1618qcafrm_create_header(u8 *buf, u16 length)19{20 __le16 len;21 22 if (!buf)23 return 0;24 25 len = cpu_to_le16(length);26 27 buf[0] = 0xAA;28 buf[1] = 0xAA;29 buf[2] = 0xAA;30 buf[3] = 0xAA;31 buf[4] = len & 0xff;32 buf[5] = (len >> 8) & 0xff;33 buf[6] = 0;34 buf[7] = 0;35 36 return QCAFRM_HEADER_LEN;37}38EXPORT_SYMBOL_GPL(qcafrm_create_header);39 40u1641qcafrm_create_footer(u8 *buf)42{43 if (!buf)44 return 0;45 46 buf[0] = 0x55;47 buf[1] = 0x55;48 return QCAFRM_FOOTER_LEN;49}50EXPORT_SYMBOL_GPL(qcafrm_create_footer);51 52/* Gather received bytes and try to extract a full ethernet frame by53 * following a simple state machine.54 *55 * Return: QCAFRM_GATHER No ethernet frame fully received yet.56 * QCAFRM_NOHEAD Header expected but not found.57 * QCAFRM_INVLEN Atheros frame length is invalid58 * QCAFRM_NOTAIL Footer expected but not found.59 * > 0 Number of byte in the fully received60 * Ethernet frame61 */62 63s3264qcafrm_fsm_decode(struct qcafrm_handle *handle, u8 *buf, u16 buf_len, u8 recv_byte)65{66 s32 ret = QCAFRM_GATHER;67 u16 len;68 69 switch (handle->state) {70 case QCAFRM_HW_LEN0:71 case QCAFRM_HW_LEN1:72 /* by default, just go to next state */73 handle->state--;74 75 if (recv_byte != 0x00) {76 /* first two bytes of length must be 0 */77 handle->state = handle->init;78 }79 break;80 case QCAFRM_HW_LEN2:81 case QCAFRM_HW_LEN3:82 handle->state--;83 break;84 /* 4 bytes header pattern */85 case QCAFRM_WAIT_AA1:86 case QCAFRM_WAIT_AA2:87 case QCAFRM_WAIT_AA3:88 case QCAFRM_WAIT_AA4:89 if (recv_byte != 0xAA) {90 ret = QCAFRM_NOHEAD;91 handle->state = handle->init;92 } else {93 handle->state--;94 }95 break;96 /* 2 bytes length. */97 /* Borrow offset field to hold length for now. */98 case QCAFRM_WAIT_LEN_BYTE0:99 handle->offset = recv_byte;100 handle->state = QCAFRM_WAIT_LEN_BYTE1;101 break;102 case QCAFRM_WAIT_LEN_BYTE1:103 handle->offset = handle->offset | (recv_byte << 8);104 handle->state = QCAFRM_WAIT_RSVD_BYTE1;105 break;106 case QCAFRM_WAIT_RSVD_BYTE1:107 handle->state = QCAFRM_WAIT_RSVD_BYTE2;108 break;109 case QCAFRM_WAIT_RSVD_BYTE2:110 len = handle->offset;111 if (len > buf_len || len < QCAFRM_MIN_LEN) {112 ret = QCAFRM_INVLEN;113 handle->state = handle->init;114 } else {115 handle->state = (enum qcafrm_state)(len + 1);116 /* Remaining number of bytes. */117 handle->offset = 0;118 }119 break;120 default:121 /* Receiving Ethernet frame itself. */122 buf[handle->offset] = recv_byte;123 handle->offset++;124 handle->state--;125 break;126 case QCAFRM_WAIT_551:127 if (recv_byte != 0x55) {128 ret = QCAFRM_NOTAIL;129 handle->state = handle->init;130 } else {131 handle->state = QCAFRM_WAIT_552;132 }133 break;134 case QCAFRM_WAIT_552:135 if (recv_byte != 0x55) {136 ret = QCAFRM_NOTAIL;137 handle->state = handle->init;138 } else {139 ret = handle->offset;140 /* Frame is fully received. */141 handle->state = handle->init;142 }143 break;144 }145 146 return ret;147}148EXPORT_SYMBOL_GPL(qcafrm_fsm_decode);149 150MODULE_DESCRIPTION("Qualcomm Atheros QCA7000 common");151MODULE_AUTHOR("Qualcomm Atheros Communications");152MODULE_AUTHOR("Stefan Wahren <wahrenst@gmx.net>");153MODULE_LICENSE("Dual BSD/GPL");154