brintos

brintos / linux-shallow public Read only

0
0
Text · 3.5 KiB · 5302da5 Raw
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