Commit f2527ec4 authored by André Carvalho de Matos's avatar André Carvalho de Matos Committed by David S. Miller

caif: Bugfix for socket priority, bindtodev and dbg channel.

Changes:
o Bugfix: SO_PRIORITY for SOL_SOCKET could not be handled
  in caif's setsockopt,  using the struct sock attribute priority instead.

o Bugfix: SO_BINDTODEVICE for SOL_SOCKET could not be handled
  in caif's setsockopt,  using the struct sock attribute ifindex instead.

o Wrong assert statement for RFM layer segmentation.

o CAIF Debug channels was not working over SPI, caif_payload_info
  containing padding info must be initialized.

o Check on pointer before dereferencing when unregister dev in caif_dev.c
Signed-off-by: default avatarSjur Braendeland <sjur.brandeland@stericsson.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 6cc0e949
...@@ -28,7 +28,7 @@ struct caif_param { ...@@ -28,7 +28,7 @@ struct caif_param {
* @sockaddr: Socket address to connect. * @sockaddr: Socket address to connect.
* @priority: Priority of the connection. * @priority: Priority of the connection.
* @link_selector: Link selector (high bandwidth or low latency) * @link_selector: Link selector (high bandwidth or low latency)
* @link_name: Name of the CAIF Link Layer to use. * @ifindex: kernel index of the interface.
* @param: Connect Request parameters (CAIF_SO_REQ_PARAM). * @param: Connect Request parameters (CAIF_SO_REQ_PARAM).
* *
* This struct is used when connecting a CAIF channel. * This struct is used when connecting a CAIF channel.
...@@ -39,7 +39,7 @@ struct caif_connect_request { ...@@ -39,7 +39,7 @@ struct caif_connect_request {
struct sockaddr_caif sockaddr; struct sockaddr_caif sockaddr;
enum caif_channel_priority priority; enum caif_channel_priority priority;
enum caif_link_selector link_selector; enum caif_link_selector link_selector;
char link_name[16]; int ifindex;
struct caif_param param; struct caif_param param;
}; };
......
...@@ -139,10 +139,10 @@ struct dev_info *cfcnfg_get_phyid(struct cfcnfg *cnfg, ...@@ -139,10 +139,10 @@ struct dev_info *cfcnfg_get_phyid(struct cfcnfg *cnfg,
enum cfcnfg_phy_preference phy_pref); enum cfcnfg_phy_preference phy_pref);
/** /**
* cfcnfg_get_named() - Get the Physical Identifier of CAIF Link Layer * cfcnfg_get_id_from_ifi() - Get the Physical Identifier of ifindex,
* it matches caif physical id with the kernel interface id.
* @cnfg: Configuration object * @cnfg: Configuration object
* @name: Name of the Physical Layer (Caif Link Layer) * @ifi: ifindex obtained from socket.c bindtodevice.
*/ */
int cfcnfg_get_named(struct cfcnfg *cnfg, char *name); int cfcnfg_get_id_from_ifi(struct cfcnfg *cnfg, int ifi);
#endif /* CFCNFG_H_ */ #endif /* CFCNFG_H_ */
...@@ -16,11 +16,18 @@ int connect_req_to_link_param(struct cfcnfg *cnfg, ...@@ -16,11 +16,18 @@ int connect_req_to_link_param(struct cfcnfg *cnfg,
{ {
struct dev_info *dev_info; struct dev_info *dev_info;
enum cfcnfg_phy_preference pref; enum cfcnfg_phy_preference pref;
int res;
memset(l, 0, sizeof(*l)); memset(l, 0, sizeof(*l));
l->priority = s->priority; /* In caif protocol low value is high priority */
l->priority = CAIF_PRIO_MAX - s->priority + 1;
if (s->link_name[0] != '\0') if (s->ifindex != 0){
l->phyid = cfcnfg_get_named(cnfg, s->link_name); res = cfcnfg_get_id_from_ifi(cnfg, s->ifindex);
if (res < 0)
return res;
l->phyid = res;
}
else { else {
switch (s->link_selector) { switch (s->link_selector) {
case CAIF_LINK_HIGH_BANDW: case CAIF_LINK_HIGH_BANDW:
......
...@@ -307,6 +307,8 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what, ...@@ -307,6 +307,8 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what,
case NETDEV_UNREGISTER: case NETDEV_UNREGISTER:
caifd = caif_get(dev); caifd = caif_get(dev);
if (caifd == NULL)
break;
netdev_info(dev, "unregister\n"); netdev_info(dev, "unregister\n");
atomic_set(&caifd->state, what); atomic_set(&caifd->state, what);
caif_device_destroy(dev); caif_device_destroy(dev);
......
...@@ -716,8 +716,7 @@ static int setsockopt(struct socket *sock, ...@@ -716,8 +716,7 @@ static int setsockopt(struct socket *sock,
{ {
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct caifsock *cf_sk = container_of(sk, struct caifsock, sk); struct caifsock *cf_sk = container_of(sk, struct caifsock, sk);
int prio, linksel; int linksel;
struct ifreq ifreq;
if (cf_sk->sk.sk_socket->state != SS_UNCONNECTED) if (cf_sk->sk.sk_socket->state != SS_UNCONNECTED)
return -ENOPROTOOPT; return -ENOPROTOOPT;
...@@ -735,33 +734,6 @@ static int setsockopt(struct socket *sock, ...@@ -735,33 +734,6 @@ static int setsockopt(struct socket *sock,
release_sock(&cf_sk->sk); release_sock(&cf_sk->sk);
return 0; return 0;
case SO_PRIORITY:
if (lvl != SOL_SOCKET)
goto bad_sol;
if (ol < sizeof(int))
return -EINVAL;
if (copy_from_user(&prio, ov, sizeof(int)))
return -EINVAL;
lock_sock(&(cf_sk->sk));
cf_sk->conn_req.priority = prio;
release_sock(&cf_sk->sk);
return 0;
case SO_BINDTODEVICE:
if (lvl != SOL_SOCKET)
goto bad_sol;
if (ol < sizeof(struct ifreq))
return -EINVAL;
if (copy_from_user(&ifreq, ov, sizeof(ifreq)))
return -EFAULT;
lock_sock(&(cf_sk->sk));
strncpy(cf_sk->conn_req.link_name, ifreq.ifr_name,
sizeof(cf_sk->conn_req.link_name));
cf_sk->conn_req.link_name
[sizeof(cf_sk->conn_req.link_name)-1] = 0;
release_sock(&cf_sk->sk);
return 0;
case CAIFSO_REQ_PARAM: case CAIFSO_REQ_PARAM:
if (lvl != SOL_CAIF) if (lvl != SOL_CAIF)
goto bad_sol; goto bad_sol;
...@@ -880,6 +852,18 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr, ...@@ -880,6 +852,18 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr,
sock->state = SS_CONNECTING; sock->state = SS_CONNECTING;
sk->sk_state = CAIF_CONNECTING; sk->sk_state = CAIF_CONNECTING;
/* Check priority value comming from socket */
/* if priority value is out of range it will be ajusted */
if (cf_sk->sk.sk_priority > CAIF_PRIO_MAX)
cf_sk->conn_req.priority = CAIF_PRIO_MAX;
else if (cf_sk->sk.sk_priority < CAIF_PRIO_MIN)
cf_sk->conn_req.priority = CAIF_PRIO_MIN;
else
cf_sk->conn_req.priority = cf_sk->sk.sk_priority;
/*ifindex = id of the interface.*/
cf_sk->conn_req.ifindex = cf_sk->sk.sk_bound_dev_if;
dbfs_atomic_inc(&cnt.num_connect_req); dbfs_atomic_inc(&cnt.num_connect_req);
cf_sk->layer.receive = caif_sktrecv_cb; cf_sk->layer.receive = caif_sktrecv_cb;
err = caif_connect_client(&cf_sk->conn_req, err = caif_connect_client(&cf_sk->conn_req,
...@@ -905,6 +889,7 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr, ...@@ -905,6 +889,7 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr,
cf_sk->maxframe = mtu - (headroom + tailroom); cf_sk->maxframe = mtu - (headroom + tailroom);
if (cf_sk->maxframe < 1) { if (cf_sk->maxframe < 1) {
pr_warn("CAIF Interface MTU too small (%d)\n", dev->mtu); pr_warn("CAIF Interface MTU too small (%d)\n", dev->mtu);
err = -ENODEV;
goto out; goto out;
} }
...@@ -1142,7 +1127,7 @@ static int caif_create(struct net *net, struct socket *sock, int protocol, ...@@ -1142,7 +1127,7 @@ static int caif_create(struct net *net, struct socket *sock, int protocol,
set_rx_flow_on(cf_sk); set_rx_flow_on(cf_sk);
/* Set default options on configuration */ /* Set default options on configuration */
cf_sk->conn_req.priority = CAIF_PRIO_NORMAL; cf_sk->sk.sk_priority= CAIF_PRIO_NORMAL;
cf_sk->conn_req.link_selector = CAIF_LINK_LOW_LATENCY; cf_sk->conn_req.link_selector = CAIF_LINK_LOW_LATENCY;
cf_sk->conn_req.protocol = protocol; cf_sk->conn_req.protocol = protocol;
/* Increase the number of sockets created. */ /* Increase the number of sockets created. */
......
...@@ -173,18 +173,15 @@ static struct cfcnfg_phyinfo *cfcnfg_get_phyinfo(struct cfcnfg *cnfg, ...@@ -173,18 +173,15 @@ static struct cfcnfg_phyinfo *cfcnfg_get_phyinfo(struct cfcnfg *cnfg,
return NULL; return NULL;
} }
int cfcnfg_get_named(struct cfcnfg *cnfg, char *name)
int cfcnfg_get_id_from_ifi(struct cfcnfg *cnfg, int ifi)
{ {
int i; int i;
for (i = 0; i < MAX_PHY_LAYERS; i++)
/* Try to match with specified name */ if (cnfg->phy_layers[i].frm_layer != NULL &&
for (i = 0; i < MAX_PHY_LAYERS; i++) { cnfg->phy_layers[i].ifindex == ifi)
if (cnfg->phy_layers[i].frm_layer != NULL return i;
&& strcmp(cnfg->phy_layers[i].phy_layer->name, return -ENODEV;
name) == 0)
return cnfg->phy_layers[i].frm_layer->id;
}
return 0;
} }
int cfcnfg_disconn_adapt_layer(struct cfcnfg *cnfg, struct cflayer *adap_layer) int cfcnfg_disconn_adapt_layer(struct cfcnfg *cnfg, struct cflayer *adap_layer)
......
...@@ -12,6 +12,8 @@ ...@@ -12,6 +12,8 @@
#include <net/caif/cfsrvl.h> #include <net/caif/cfsrvl.h>
#include <net/caif/cfpkt.h> #include <net/caif/cfpkt.h>
#define container_obj(layr) ((struct cfsrvl *) layr)
static int cfdbgl_receive(struct cflayer *layr, struct cfpkt *pkt); static int cfdbgl_receive(struct cflayer *layr, struct cfpkt *pkt);
static int cfdbgl_transmit(struct cflayer *layr, struct cfpkt *pkt); static int cfdbgl_transmit(struct cflayer *layr, struct cfpkt *pkt);
...@@ -38,5 +40,17 @@ static int cfdbgl_receive(struct cflayer *layr, struct cfpkt *pkt) ...@@ -38,5 +40,17 @@ static int cfdbgl_receive(struct cflayer *layr, struct cfpkt *pkt)
static int cfdbgl_transmit(struct cflayer *layr, struct cfpkt *pkt) static int cfdbgl_transmit(struct cflayer *layr, struct cfpkt *pkt)
{ {
struct cfsrvl *service = container_obj(layr);
struct caif_payload_info *info;
int ret;
if (!cfsrvl_ready(service, &ret))
return ret;
/* Add info for MUX-layer to route the packet out */
info = cfpkt_info(pkt);
info->channel_id = service->layer.id;
info->dev_info = &service->dev_info;
return layr->dn->transmit(layr->dn, pkt); return layr->dn->transmit(layr->dn, pkt);
} }
...@@ -193,7 +193,7 @@ static int cfrfml_receive(struct cflayer *layr, struct cfpkt *pkt) ...@@ -193,7 +193,7 @@ static int cfrfml_receive(struct cflayer *layr, struct cfpkt *pkt)
static int cfrfml_transmit_segment(struct cfrfml *rfml, struct cfpkt *pkt) static int cfrfml_transmit_segment(struct cfrfml *rfml, struct cfpkt *pkt)
{ {
caif_assert(cfpkt_getlen(pkt) >= rfml->fragment_size); caif_assert(cfpkt_getlen(pkt) < rfml->fragment_size);
/* Add info for MUX-layer to route the packet out. */ /* Add info for MUX-layer to route the packet out. */
cfpkt_info(pkt)->channel_id = rfml->serv.layer.id; cfpkt_info(pkt)->channel_id = rfml->serv.layer.id;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment