Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1619cb6f authored by Chris Kelly's avatar Chris Kelly Committed by Greg Kroah-Hartman
Browse files

staging: ozwpan: Added basic L2 protocol support



Added the basic implementation of the L2 protocol support used to
communicate with devices over the network.

Signed-off-by: default avatarChris Kelly <ckelly@ozmodevices.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 62450bca
Loading
Loading
Loading
Loading
+957 −0

File added.

Preview size limit exceeded, changes collapsed.

+69 −0
Original line number Original line Diff line number Diff line
/* -----------------------------------------------------------------------------
 * Copyright (c) 2011 Ozmo Inc
 * Released under the GNU General Public License Version 2 (GPLv2).
 * -----------------------------------------------------------------------------
 */
#ifndef _OZPROTO_H
#define _OZPROTO_H

#include <asm/byteorder.h>
#include "ozconfig.h"
#include "ozappif.h"

#define OZ_ALLOCATED_SPACE(__x)	(LL_RESERVED_SPACE(__x)+(__x)->needed_tailroom)

/* Converts millisecs to jiffies.
 */
#define oz_ms_to_jiffies(__x)	(((__x)*1000)/HZ)

/* Quantum milliseconds.
 */
#define OZ_QUANTUM_MS		8
/* Quantum jiffies
 */
#define OZ_QUANTUM_J		(oz_ms_to_jiffies(OZ_QUANTUM_MS))
/* Default timeouts.
 */
#define OZ_CONNECTION_TOUT_J	(2*HZ)
#define OZ_PRESLEEP_TOUT_J	(11*HZ)

/* Maximun sizes of tx frames. */
#define OZ_MAX_TX_SIZE		1514

/* Application handler functions.
 */
typedef int (*oz_app_init_fn_t)(void);
typedef void (*oz_app_term_fn_t)(void);
typedef int (*oz_app_start_fn_t)(struct oz_pd *pd, int resume);
typedef void (*oz_app_stop_fn_t)(struct oz_pd *pd, int pause);
typedef void (*oz_app_rx_fn_t)(struct oz_pd *pd, struct oz_elt *elt);
typedef int (*oz_app_hearbeat_fn_t)(struct oz_pd *pd);
typedef void (*oz_app_farewell_fn_t)(struct oz_pd *pd, u8 ep_num,
			u8 *data, u8 len);

struct oz_app_if {
	oz_app_init_fn_t	init;
	oz_app_term_fn_t	term;
	oz_app_start_fn_t	start;
	oz_app_stop_fn_t	stop;
	oz_app_rx_fn_t		rx;
	oz_app_hearbeat_fn_t	heartbeat;
	oz_app_farewell_fn_t	farewell;
	int			app_id;
};

int oz_protocol_init(char *devs);
void oz_protocol_term(void);
int oz_get_pd_list(struct oz_mac_addr *addr, int max_count);
void oz_app_enable(int app_id, int enable);
struct oz_pd *oz_pd_find(u8 *mac_addr);
void oz_binding_add(char *net_dev);
void oz_binding_remove(char *net_dev);
void oz_timer_add(struct oz_pd *pd, int type, unsigned long due_time,
		int remove);
void oz_timer_delete(struct oz_pd *pd, int type);
void oz_pd_request_heartbeat(struct oz_pd *pd);
void oz_polling_lock_bh(void);
void oz_polling_unlock_bh(void);

#endif /* _OZPROTO_H */
+372 −0
Original line number Original line Diff line number Diff line
/* -----------------------------------------------------------------------------
 * Copyright (c) 2011 Ozmo Inc
 * Released under the GNU General Public License Version 2 (GPLv2).
 * -----------------------------------------------------------------------------
 */
#ifndef _OZPROTOCOL_H
#define _OZPROTOCOL_H

#define PACKED __packed

#define OZ_ETHERTYPE 0x892e

/* Status codes
 */
#define OZ_STATUS_SUCCESS		0
#define OZ_STATUS_INVALID_PARAM		1
#define OZ_STATUS_TOO_MANY_PDS		2
#define OZ_STATUS_NOT_ALLOWED		4
#define OZ_STATUS_SESSION_MISMATCH	5
#define OZ_STATUS_SESSION_TEARDOWN	6

/* This is the generic element header.
   Every element starts with this.
 */
struct oz_elt {
	u8 type;
	u8 length;
} PACKED;

#define oz_next_elt(__elt)	\
	(struct oz_elt *)((u8 *)((__elt) + 1) + (__elt)->length)

/* Protocol element IDs.
 */
#define OZ_ELT_CONNECT_REQ	0x06
#define OZ_ELT_CONNECT_RSP	0x07
#define OZ_ELT_DISCONNECT	0x08
#define OZ_ELT_UPDATE_PARAM_REQ	0x11
#define OZ_ELT_FAREWELL_REQ	0x12
#define OZ_ELT_APP_DATA		0x31

/* This is the Ozmo header which is the first Ozmo specific part
 * of a frame and comes after the MAC header.
 */
struct oz_hdr {
	u8	control;
	u8	last_pkt_num;
	u32	pkt_num;
} PACKED;

#define OZ_PROTOCOL_VERSION	0x1
/* Bits in the control field. */
#define OZ_VERSION_MASK		0xc
#define OZ_VERSION_SHIFT	2
#define OZ_F_ACK		0x10
#define OZ_F_ISOC		0x20
#define OZ_F_MORE_DATA		0x40
#define OZ_F_ACK_REQUESTED	0x80

#define oz_get_prot_ver(__x)	(((__x) & OZ_VERSION_MASK) >> OZ_VERSION_SHIFT)

/* Used to select the bits of packet number to put in the last_pkt_num.
 */
#define OZ_LAST_PN_MASK		0x00ff

#define OZ_LAST_PN_HALF_CYCLE	127

/* Connect request data structure.
 */
struct oz_elt_connect_req {
	u8	mode;
	u8	resv1[16];
	u8	pd_info;
	u8	session_id;
	u8	presleep;
	u8	resv2;
	u8	host_vendor;
	u8	keep_alive;
	u16	apps;
	u8	max_len_div16;
	u8	ms_per_isoc;
	u8	resv3[2];
} PACKED;

/* mode field bits.
 */
#define OZ_MODE_POLLED		0x0
#define OZ_MODE_TRIGGERED	0x1
#define OZ_MODE_MASK		0xf
#define OZ_F_ISOC_NO_ELTS	0x40
#define OZ_F_ISOC_ANYTIME	0x80

/* Keep alive field.
 */
#define OZ_KALIVE_TYPE_MASK	0xc0
#define OZ_KALIVE_VALUE_MASK	0x3f
#define OZ_KALIVE_SPECIAL	0x00
#define OZ_KALIVE_SECS		0x40
#define OZ_KALIVE_MINS		0x80
#define OZ_KALIVE_HOURS		0xc0

/* Connect response data structure.
 */
struct oz_elt_connect_rsp {
	u8	mode;
	u8	status;
	u8	resv1[3];
	u8	session_id;
	u16	apps;
	u32	resv2;
} PACKED;

struct oz_elt_farewell {
	u8	ep_num;
	u8	index;
	u8	report[1];
} PACKED;

struct oz_elt_update_param {
	u8	resv1[16];
	u8	presleep;
	u8	resv2;
	u8	host_vendor;
	u8	keepalive;
} PACKED;

/* Header common to all application elements.
 */
struct oz_app_hdr {
	u8	app_id;
	u8	elt_seq_num;
} PACKED;

/* Values for app_id.
 */
#define OZ_APPID_USB				0x1
#define OZ_APPID_UNUSED1			0x2
#define OZ_APPID_UNUSED2			0x3
#define OZ_APPID_SERIAL				0x4
#define OZ_APPID_MAX				OZ_APPID_SERIAL
#define OZ_NB_APPS				(OZ_APPID_MAX+1)

/* USB header common to all elements for the  USB application.
 * This header extends the oz_app_hdr and comes directly after
 * the element header in a USB application.
 */
struct oz_usb_hdr {
	u8	app_id;
	u8	elt_seq_num;
	u8	type;
} PACKED;



/* USB requests element subtypes (type field of hs_usb_hdr).
 */
#define OZ_GET_DESC_REQ			1
#define OZ_GET_DESC_RSP			2
#define OZ_SET_CONFIG_REQ		3
#define OZ_SET_CONFIG_RSP		4
#define OZ_SET_INTERFACE_REQ		5
#define OZ_SET_INTERFACE_RSP		6
#define OZ_VENDOR_CLASS_REQ		7
#define OZ_VENDOR_CLASS_RSP		8
#define OZ_GET_STATUS_REQ		9
#define OZ_GET_STATUS_RSP		10
#define OZ_CLEAR_FEATURE_REQ		11
#define OZ_CLEAR_FEATURE_RSP		12
#define OZ_SET_FEATURE_REQ		13
#define OZ_SET_FEATURE_RSP		14
#define OZ_GET_CONFIGURATION_REQ	15
#define OZ_GET_CONFIGURATION_RSP	16
#define OZ_GET_INTERFACE_REQ		17
#define OZ_GET_INTERFACE_RSP		18
#define OZ_SYNCH_FRAME_REQ		19
#define OZ_SYNCH_FRAME_RSP		20
#define OZ_USB_ENDPOINT_DATA		23

#define OZ_REQD_D2H			0x80

struct oz_get_desc_req {
	u8	app_id;
	u8	elt_seq_num;
	u8	type;
	u8	req_id;
	u16	offset;
	u16	size;
	u8	req_type;
	u8	desc_type;
	u16	w_index;
	u8	index;
} PACKED;

/* Values for desc_type field.
*/
#define OZ_DESC_DEVICE			0x01
#define OZ_DESC_CONFIG			0x02
#define OZ_DESC_STRING			0x03

/* Values for req_type field.
 */
#define OZ_RECP_MASK			0x1F
#define OZ_RECP_DEVICE			0x00
#define OZ_RECP_INTERFACE		0x01
#define OZ_RECP_ENDPOINT		0x02

#define OZ_REQT_MASK			0x60
#define OZ_REQT_STD			0x00
#define OZ_REQT_CLASS			0x20
#define OZ_REQT_VENDOR			0x40

struct oz_get_desc_rsp {
	u8	app_id;
	u8	elt_seq_num;
	u8	type;
	u8	req_id;
	u16	offset;
	u16	total_size;
	u8	rcode;
	u8	data[1];
} PACKED;

struct oz_feature_req {
	u8	app_id;
	u8	elt_seq_num;
	u8	type;
	u8	req_id;
	u8	recipient;
	u8	index;
	u16	feature;
} PACKED;

struct oz_feature_rsp {
	u8	app_id;
	u8	elt_seq_num;
	u8	type;
	u8	req_id;
	u8	rcode;
} PACKED;

struct oz_set_config_req {
	u8	app_id;
	u8	elt_seq_num;
	u8	type;
	u8	req_id;
	u8	index;
} PACKED;

struct oz_set_config_rsp {
	u8	app_id;
	u8	elt_seq_num;
	u8	type;
	u8	req_id;
	u8	rcode;
} PACKED;

struct oz_set_interface_req {
	u8	app_id;
	u8	elt_seq_num;
	u8	type;
	u8	req_id;
	u8	index;
	u8	alternative;
} PACKED;

struct oz_set_interface_rsp {
	u8	app_id;
	u8	elt_seq_num;
	u8	type;
	u8	req_id;
	u8	rcode;
} PACKED;

struct oz_get_interface_req {
	u8	app_id;
	u8	elt_seq_num;
	u8	type;
	u8	req_id;
	u8	index;
} PACKED;

struct oz_get_interface_rsp {
	u8	app_id;
	u8	elt_seq_num;
	u8	type;
	u8	req_id;
	u8	rcode;
	u8	alternative;
} PACKED;

struct oz_vendor_class_req {
	u8	app_id;
	u8	elt_seq_num;
	u8	type;
	u8	req_id;
	u8	req_type;
	u8	request;
	u16	value;
	u16	index;
	u8	data[1];
} PACKED;

struct oz_vendor_class_rsp {
	u8	app_id;
	u8	elt_seq_num;
	u8	type;
	u8	req_id;
	u8	rcode;
	u8	data[1];
} PACKED;

struct oz_data {
	u8	app_id;
	u8	elt_seq_num;
	u8	type;
	u8	endpoint;
	u8	format;
} PACKED;

struct oz_isoc_fixed {
	u8	app_id;
	u8	elt_seq_num;
	u8	type;
	u8	endpoint;
	u8	format;
	u8	unit_size;
	u8	frame_number;
	u8	data[1];
} PACKED;

struct oz_multiple_fixed {
	u8	app_id;
	u8	elt_seq_num;
	u8	type;
	u8	endpoint;
	u8	format;
	u8	unit_size;
	u8	data[1];
} PACKED;

struct oz_fragmented {
	u8	app_id;
	u8	elt_seq_num;
	u8	type;
	u8	endpoint;
	u8	format;
	u16	total_size;
	u16	offset;
	u8	data[1];
} PACKED;

/* Note: the following does not get packaged in an element in the same way
 * that other data formats are packaged. Instead the data is put in a frame
 * directly after the oz_header and is the only permitted data in such a
 * frame. The length of the data is directly determined from the frame size.
 */
struct oz_isoc_large {
	u8	endpoint;
	u8	format;
	u8	ms_data;
	u8	frame_number;
} PACKED;

#define OZ_DATA_F_TYPE_MASK		0xF
#define OZ_DATA_F_MULTIPLE_FIXED	0x1
#define OZ_DATA_F_MULTIPLE_VAR		0x2
#define OZ_DATA_F_ISOC_FIXED		0x3
#define OZ_DATA_F_ISOC_VAR		0x4
#define OZ_DATA_F_FRAGMENTED		0x5
#define OZ_DATA_F_ISOC_LARGE		0x7

#endif /* _OZPROTOCOL_H */