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

Commit bee925db authored by sjur.brandeland@stericsson.com's avatar sjur.brandeland@stericsson.com Committed by David S. Miller
Browse files

caif: prepare support for namespaces



Use struct net to reference CAIF configuration object instead of static variables.
Refactor functions caif_connect_client, caif_disconnect_client and squach
files cfcnfg.c and caif_config_utils.

Signed-off-by: default avatarSjur Brændeland <sjur.brandeland@stericsson.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b3ccfbe4
Loading
Loading
Loading
Loading
+6 −18
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@
#include <net/caif/cfcnfg.h>
#include <linux/caif/caif_socket.h>
#include <linux/if.h>
#include <linux/net.h>

/**
 * struct caif_param - CAIF parameters.
@@ -62,16 +63,18 @@ struct caif_connect_request {
 * E.g. CAIF Socket will call this function for each socket it connects
 * and have one client_layer instance for each socket.
 */
int caif_connect_client(struct caif_connect_request *conn_req,
int caif_connect_client(struct net *net,
			struct caif_connect_request *conn_req,
			struct cflayer *client_layer, int *ifindex,
			int *headroom, int *tailroom);

/**
 * caif_disconnect_client - Disconnects a client from the CAIF stack.
 *
 * @client_layer: Client layer to be removed.
 * @client_layer: Client layer to be disconnected.
 */
int caif_disconnect_client(struct cflayer *client_layer);
int caif_disconnect_client(struct net *net, struct cflayer *client_layer);


/**
 * caif_client_register_refcnt - register ref-count functions provided by client.
@@ -90,21 +93,6 @@ int caif_disconnect_client(struct cflayer *client_layer);
void caif_client_register_refcnt(struct cflayer *adapt_layer,
					void (*hold)(struct cflayer *lyr),
					void (*put)(struct cflayer *lyr));
/**
 * caif_connect_req_to_link_param - Translate configuration parameters
 *				    from socket format to internal format.
 * @cnfg:	Pointer to configuration handler
 * @con_req:	Configuration parameters supplied in function
 *		caif_connect_client
 * @channel_setup_param: Parameters supplied to the CAIF Core stack for
 *			 setting up channels.
 *
 */

int caif_connect_req_to_link_param(struct cfcnfg *cnfg,
				   struct caif_connect_request *con_req,
				   struct cfctrl_link_param *setup_param);

/**
 * caif_free_client - Free memory used to manage the client in the CAIF Stack.
 *
+8 −63
Original line number Diff line number Diff line
@@ -45,6 +45,12 @@ enum cfcnfg_phy_preference {
	CFPHYPREF_LOOP
};

/**
 * cfcnfg_create() - Get the CAIF configuration object given network.
 * @net:	Network for the CAIF configuration object.
 */
struct cfcnfg *get_cfcnfg(struct net *net);

/**
 * cfcnfg_create() - Create the CAIF configuration object.
 */
@@ -65,17 +71,15 @@ void cfcnfg_remove(struct cfcnfg *cfg);
 * @dev:	Pointer to link layer device
 * @phy_layer:	Specify the physical layer. The transmit function
 *		MUST be set in the structure.
 * @phyid:	The assigned physical ID for this layer, used in
 *		cfcnfg_add_adapt_layer to specify PHY for the link.
 * @pref:	The phy (link layer) preference.
 * @fcs:	Specify if checksum is used in CAIF Framing Layer.
 * @stx:	Specify if Start Of Frame extension is used.
 * @stx:	Specify if Start Of Frame eXtention is used.
 */

void
cfcnfg_add_phy_layer(struct cfcnfg *cnfg, enum cfcnfg_phy_type phy_type,
		     struct net_device *dev, struct cflayer *phy_layer,
		     u16 *phyid, enum cfcnfg_phy_preference pref,
		     enum cfcnfg_phy_preference pref,
		     bool fcs, bool stx);

/**
@@ -87,65 +91,6 @@ cfcnfg_add_phy_layer(struct cfcnfg *cnfg, enum cfcnfg_phy_type phy_type,
 */
int cfcnfg_del_phy_layer(struct cfcnfg *cnfg, struct cflayer *phy_layer);

/**
 * cfcnfg_disconn_adapt_layer - Disconnects an adaptation layer.
 *
 * @cnfg:	Pointer to a CAIF configuration object, created by
 *		cfcnfg_create().
 * @adap_layer: Adaptation layer to be removed.
 */
int cfcnfg_disconn_adapt_layer(struct cfcnfg *cnfg,
			struct cflayer *adap_layer);

/**
 * cfcnfg_release_adap_layer - Used by client to release the adaptation layer.
 *
 * @adap_layer: Adaptation layer.
 */
void cfcnfg_release_adap_layer(struct cflayer *adap_layer);

/**
 * cfcnfg_add_adaptation_layer - Add an adaptation layer to the CAIF stack.
 *
 * The adaptation Layer is where the interface to application or higher-level
 * driver functionality is implemented.
 *
 * @cnfg:		Pointer to a CAIF configuration object, created by
 *			cfcnfg_create().
 * @param:		Link setup parameters.
 * @adap_layer:		Specify the adaptation layer; the receive and
 *			flow-control functions MUST be set in the structure.
 * @ifindex:		Link layer interface index used for this connection.
 * @proto_head:		Protocol head-space needed by CAIF protocol,
 *			excluding link layer.
 * @proto_tail:		Protocol tail-space needed by CAIF protocol,
 *			excluding link layer.
 */
int cfcnfg_add_adaptation_layer(struct cfcnfg *cnfg,
			    struct cfctrl_link_param *param,
			    struct cflayer *adap_layer,
			    int *ifindex,
			    int *proto_head,
			    int *proto_tail);

/**
 * cfcnfg_get_phyid() - Get physical ID, given type.
 * Returns one of the physical interfaces matching the given type.
 * Zero if no match is found.
 * @cnfg:	Configuration object
 * @phy_pref:	Caif Link Layer preference
 */
struct dev_info *cfcnfg_get_phyid(struct cfcnfg *cnfg,
		     enum cfcnfg_phy_preference phy_pref);

/**
 * cfcnfg_get_id_from_ifi() - Get the Physical Identifier of ifindex,
 * 			it matches caif physical id with the kernel interface id.
 * @cnfg:	Configuration object
 * @ifi:	ifindex obtained from socket.c bindtodevice.
 */
int cfcnfg_get_id_from_ifi(struct cfcnfg *cnfg, int ifi);

/**
 * cfcnfg_set_phy_state() - Set the state of the physical interface device.
 * @cnfg:	Configuration object
+1 −1
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@ caif-y := caif_dev.o \
	cffrml.o cfveil.o cfdbgl.o\
	cfserl.o cfdgml.o  \
	cfrfml.o cfvidl.o cfutill.o \
	cfsrvl.o cfpkt_skbuff.o caif_config_util.o
	cfsrvl.o cfpkt_skbuff.o

obj-$(CONFIG_CAIF) += caif.o
obj-$(CONFIG_CAIF_NETDEV) += chnl_net.o

net/caif/caif_config_util.c

deleted100644 → 0
+0 −99
Original line number Diff line number Diff line
/*
 * Copyright (C) ST-Ericsson AB 2010
 * Author:	Sjur Brendeland sjur.brandeland@stericsson.com
 * License terms: GNU General Public License (GPL) version 2
 */

#include <linux/module.h>
#include <linux/spinlock.h>
#include <net/caif/cfctrl.h>
#include <net/caif/cfcnfg.h>
#include <net/caif/caif_dev.h>

int caif_connect_req_to_link_param(struct cfcnfg *cnfg,
				   struct caif_connect_request *s,
				   struct cfctrl_link_param *l)
{
	struct dev_info *dev_info;
	enum cfcnfg_phy_preference pref;
	int res;

	memset(l, 0, sizeof(*l));
	/* In caif protocol low value is high priority */
	l->priority = CAIF_PRIO_MAX - s->priority + 1;

	if (s->ifindex != 0){
		res = cfcnfg_get_id_from_ifi(cnfg, s->ifindex);
		if (res < 0)
			return res;
		l->phyid = res;
	}
	else {
		switch (s->link_selector) {
		case CAIF_LINK_HIGH_BANDW:
			pref = CFPHYPREF_HIGH_BW;
			break;
		case CAIF_LINK_LOW_LATENCY:
			pref = CFPHYPREF_LOW_LAT;
			break;
		default:
			return -EINVAL;
		}
		dev_info = cfcnfg_get_phyid(cnfg, pref);
		if (dev_info == NULL)
			return -ENODEV;
		l->phyid = dev_info->id;
	}
	switch (s->protocol) {
	case CAIFPROTO_AT:
		l->linktype = CFCTRL_SRV_VEI;
		if (s->sockaddr.u.at.type == CAIF_ATTYPE_PLAIN)
			l->chtype = 0x02;
		else
			l->chtype = s->sockaddr.u.at.type;
		l->endpoint = 0x00;
		break;
	case CAIFPROTO_DATAGRAM:
		l->linktype = CFCTRL_SRV_DATAGRAM;
		l->chtype = 0x00;
		l->u.datagram.connid = s->sockaddr.u.dgm.connection_id;
		break;
	case CAIFPROTO_DATAGRAM_LOOP:
		l->linktype = CFCTRL_SRV_DATAGRAM;
		l->chtype = 0x03;
		l->endpoint = 0x00;
		l->u.datagram.connid = s->sockaddr.u.dgm.connection_id;
		break;
	case CAIFPROTO_RFM:
		l->linktype = CFCTRL_SRV_RFM;
		l->u.datagram.connid = s->sockaddr.u.rfm.connection_id;
		strncpy(l->u.rfm.volume, s->sockaddr.u.rfm.volume,
			sizeof(l->u.rfm.volume)-1);
		l->u.rfm.volume[sizeof(l->u.rfm.volume)-1] = 0;
		break;
	case CAIFPROTO_UTIL:
		l->linktype = CFCTRL_SRV_UTIL;
		l->endpoint = 0x00;
		l->chtype = 0x00;
		strncpy(l->u.utility.name, s->sockaddr.u.util.service,
			sizeof(l->u.utility.name)-1);
		l->u.utility.name[sizeof(l->u.utility.name)-1] = 0;
		caif_assert(sizeof(l->u.utility.name) > 10);
		l->u.utility.paramlen = s->param.size;
		if (l->u.utility.paramlen > sizeof(l->u.utility.params))
			l->u.utility.paramlen = sizeof(l->u.utility.params);

		memcpy(l->u.utility.params, s->param.data,
		       l->u.utility.paramlen);

		break;
	case CAIFPROTO_DEBUG:
		l->linktype = CFCTRL_SRV_DBG;
		l->endpoint = s->sockaddr.u.dbg.service;
		l->chtype = s->sockaddr.u.dbg.type;
		break;
	default:
		return -EINVAL;
	}
	return 0;
}
+36 −41
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@
#include <net/net_namespace.h>
#include <net/pkt_sched.h>
#include <net/caif/caif_device.h>
#include <net/caif/caif_dev.h>
#include <net/caif/caif_layer.h>
#include <net/caif/cfpkt.h>
#include <net/caif/cfcnfg.h>
@@ -43,11 +42,21 @@ struct caif_device_entry_list {
};

struct caif_net {
	struct cfcnfg *cfg;
	struct caif_device_entry_list caifdevs;
};

static int caif_net_id;
static struct cfcnfg *cfg;

struct cfcnfg *get_cfcnfg(struct net *net)
{
	struct caif_net *caifn;
	BUG_ON(!net);
	caifn = net_generic(net, caif_net_id);
	BUG_ON(!caifn);
	return caifn->cfg;
}
EXPORT_SYMBOL(get_cfcnfg);

static struct caif_device_entry_list *caif_device_list(struct net *net)
{
@@ -191,12 +200,17 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what,
	struct caif_dev_common *caifdev;
	enum cfcnfg_phy_preference pref;
	enum cfcnfg_phy_type phy_type;
	struct cfcnfg *cfg;
	struct caif_device_entry_list *caifdevs =
	    caif_device_list(dev_net(dev));

	if (dev->type != ARPHRD_CAIF)
		return 0;

	cfg = get_cfcnfg(dev_net(dev));
	if (cfg == NULL)
		return 0;

	switch (what) {
	case NETDEV_REGISTER:
		caifd = caif_device_alloc(dev);
@@ -235,7 +249,6 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what,
				     phy_type,
				     dev,
				     &caifd->layer,
				     0,
				     pref,
				     caifdev->use_fcs,
				     caifdev->use_stx);
@@ -323,35 +336,20 @@ static struct notifier_block caif_device_notifier = {
	.priority = 0,
};

int caif_connect_client(struct caif_connect_request *conn_req,
		       struct cflayer *client_layer, int *ifindex,
		       int *headroom, int *tailroom)
{
	struct cfctrl_link_param param;
	int ret;

	ret = caif_connect_req_to_link_param(cfg, conn_req, &param);
	if (ret)
		return ret;
	/* Hook up the adaptation layer. */
	return cfcnfg_add_adaptation_layer(cfg, &param,
				       client_layer, ifindex,
				       headroom, tailroom);
}
EXPORT_SYMBOL(caif_connect_client);

int caif_disconnect_client(struct cflayer *adap_layer)
{
	return cfcnfg_disconn_adapt_layer(cfg, adap_layer);
}
EXPORT_SYMBOL(caif_disconnect_client);

/* Per-namespace Caif devices handling */
static int caif_init_net(struct net *net)
{
	struct caif_net *caifn = net_generic(net, caif_net_id);
	BUG_ON(!caifn);
	INIT_LIST_HEAD(&caifn->caifdevs.list);
	mutex_init(&caifn->caifdevs.lock);

	caifn->cfg = cfcnfg_create();
	if (!caifn->cfg) {
		pr_warn("can't create cfcnfg\n");
		return -ENOMEM;
	}

	return 0;
}

@@ -360,10 +358,17 @@ static void caif_exit_net(struct net *net)
	struct caif_device_entry *caifd, *tmp;
	struct caif_device_entry_list *caifdevs =
	    caif_device_list(net);
	struct cfcnfg *cfg;

	rtnl_lock();
	mutex_lock(&caifdevs->lock);

	cfg = get_cfcnfg(net);
	if (cfg == NULL) {
		mutex_unlock(&caifdevs->lock);
		return;
	}

	list_for_each_entry_safe(caifd, tmp, &caifdevs->list, list) {
		int i = 0;
		list_del_rcu(&caifd->list);
@@ -382,7 +387,7 @@ static void caif_exit_net(struct net *net)
		free_percpu(caifd->pcpu_refcnt);
		kfree(caifd);
	}

	cfcnfg_remove(cfg);

	mutex_unlock(&caifdevs->lock);
	rtnl_unlock();
@@ -400,32 +405,22 @@ static int __init caif_device_init(void)
{
	int result;

	cfg = cfcnfg_create();
	if (!cfg) {
		pr_warn("can't create cfcnfg\n");
		goto err_cfcnfg_create_failed;
	}
	result = register_pernet_device(&caif_net_ops);

	if (result) {
		kfree(cfg);
		cfg = NULL;
	if (result)
		return result;
	}
	dev_add_pack(&caif_packet_type);

	register_netdevice_notifier(&caif_device_notifier);
	dev_add_pack(&caif_packet_type);

	return result;
err_cfcnfg_create_failed:
	return -ENODEV;
}

static void __exit caif_device_exit(void)
{
	dev_remove_pack(&caif_packet_type);
	unregister_pernet_device(&caif_net_ops);
	unregister_netdevice_notifier(&caif_device_notifier);
	cfcnfg_remove(cfg);
	dev_remove_pack(&caif_packet_type);
}

module_init(caif_device_init);
Loading