#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__
#include <linux/stddef.h>
#include <linux/spinlock.h>
#include <asm/unaligned.h>
#include <net/caif/caif_layer.h>
#include <net/caif/cfsrvl.h>
#include <net/caif/cfpkt.h>
#define container_obj(layr) container_of(layr, struct cfrfml, serv.layer)
#define RFM_SEGMENTATION_BIT 0x01
static int cfrfml_receive(struct cflayer *layr, struct cfpkt *pkt);
static int cfrfml_transmit(struct cflayer *layr, struct cfpkt *pkt);
struct cfpkt *incomplete_frm;
static void cfrfml_release(struct cflayer *layer)
struct cfsrvl *srvl = container_of(layer, struct cfsrvl, layer);
struct cfrfml *rfml = container_obj(&srvl->layer);
if (rfml->incomplete_frm)
cfpkt_destroy(rfml->incomplete_frm);
struct cflayer *cfrfml_create(u8 channel_id, struct dev_info *dev_info,
struct cfrfml *this = kzalloc(sizeof(struct cfrfml), GFP_ATOMIC);
cfsrvl_init(&this->serv, channel_id, dev_info, false);
this->serv.release = cfrfml_release;
this->serv.layer.receive = cfrfml_receive;
this->serv.layer.transmit = cfrfml_transmit;
tmp = (mtu_size - RFM_HEAD_SIZE - 6) / 16;
this->fragment_size = tmp;
spin_lock_init(&this->sync);
snprintf(this->serv.layer.name, CAIF_LAYER_NAME_SZ,
return &this->serv.layer;
static struct cfpkt *rfm_append(struct cfrfml *rfml, char *seghead,
struct cfpkt *pkt, int *err)
if (cfpkt_extr_head(pkt, seghead, 6) < 0)
if (memcmp(seghead, rfml->seghead, 6) != 0)
tmppkt = cfpkt_append(rfml->incomplete_frm, pkt,
rfml->pdu_size + RFM_HEAD_SIZE);