caif: set traffic class for caif packets
authorDmitry Tarnyagin <dmitry.tarnyagin@stericsson.com>
Thu, 12 Apr 2012 08:27:24 +0000 (08:27 +0000)
committerDavid S. Miller <davem@davemloft.net>
Fri, 13 Apr 2012 15:37:36 +0000 (11:37 -0400)
Set traffic class for CAIF packets, based on socket
priority, CAIF protocol type, or type of message.

Traffic class mapping for different packet types:
 - control:       TC_PRIO_CONTROL;
 - flow control:  TC_PRIO_CONTROL;
 - at:            TC_PRIO_CONTROL;
 - rfm:           TC_PRIO_INTERACTIVE_BULK;
 - other sockets: equals to socket's TC;
 - network data:  no change.

Signed-off-by: Dmitry Tarnyagin <dmitry.tarnyagin@stericsson.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/caif/cfpkt.h
net/caif/caif_socket.c
net/caif/cfctrl.c
net/caif/cfpkt_skbuff.c
net/caif/cfsrvl.c

index 6bd200a4754ac99d45058595916f1dcf81ddec99..83a89ba3005b1efb211af792a08e9d6060174e47 100644 (file)
@@ -188,11 +188,18 @@ struct cfpkt *cfpkt_fromnative(enum caif_direction dir, void *nativepkt);
  */
 void *cfpkt_tonative(struct cfpkt *pkt);
 
-
 /*
  * Returns packet information for a packet.
  * pkt Packet to get info from;
  * @return Packet information
  */
 struct caif_payload_info *cfpkt_info(struct cfpkt *pkt);
+
+/** cfpkt_set_prio - set priority for a CAIF packet.
+ *
+ * @pkt: The CAIF packet to be adjusted.
+ * @prio: one of TC_PRIO_ constants.
+ */
+void cfpkt_set_prio(struct cfpkt *pkt, int prio);
+
 #endif                         /* CFPKT_H_ */
index 5016fa57b6231742112083fa06eaf383e7a60154..ce47ee9f48c8418441d437688a47d5ea3b23ef93 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/uaccess.h>
 #include <linux/debugfs.h>
 #include <linux/caif/caif_socket.h>
-#include <linux/atomic.h>
+#include <linux/pkt_sched.h>
 #include <net/sock.h>
 #include <net/tcp_states.h>
 #include <net/caif/caif_layer.h>
@@ -505,6 +505,7 @@ static int transmit_skb(struct sk_buff *skb, struct caifsock *cf_sk,
 
        pkt = cfpkt_fromnative(CAIF_DIR_OUT, skb);
        memset(skb->cb, 0, sizeof(struct caif_payload_info));
+       cfpkt_set_prio(pkt, cf_sk->sk.sk_priority);
 
        if (cf_sk->layer.dn == NULL) {
                kfree_skb(skb);
@@ -1062,6 +1063,18 @@ static int caif_create(struct net *net, struct socket *sock, int protocol,
        /* Store the protocol */
        sk->sk_protocol = (unsigned char) protocol;
 
+       /* Initialize default priority for well-known cases */
+       switch (protocol) {
+       case CAIFPROTO_AT:
+               sk->sk_priority = TC_PRIO_CONTROL;
+               break;
+       case CAIFPROTO_RFM:
+               sk->sk_priority = TC_PRIO_INTERACTIVE_BULK;
+               break;
+       default:
+               sk->sk_priority = TC_PRIO_BESTEFFORT;
+       }
+
        /*
         * Lock in order to try to stop someone from opening the socket
         * too early.
@@ -1081,7 +1094,6 @@ static int caif_create(struct net *net, struct socket *sock, int protocol,
        set_rx_flow_on(cf_sk);
 
        /* Set default options on configuration */
-       cf_sk->sk.sk_priority = CAIF_PRIO_NORMAL;
        cf_sk->conn_req.link_selector = CAIF_LINK_LOW_LATENCY;
        cf_sk->conn_req.protocol = protocol;
        release_sock(&cf_sk->sk);
index 5cf52225692e878228653b68610eb363c5d165df..047cd0eec022f2465b55637f8d374c8540138fe5 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/stddef.h>
 #include <linux/spinlock.h>
 #include <linux/slab.h>
+#include <linux/pkt_sched.h>
 #include <net/caif/caif_layer.h>
 #include <net/caif/cfpkt.h>
 #include <net/caif/cfctrl.h>
@@ -189,6 +190,7 @@ void cfctrl_enum_req(struct cflayer *layer, u8 physlinkid)
        cfctrl->serv.dev_info.id = physlinkid;
        cfpkt_addbdy(pkt, CFCTRL_CMD_ENUM);
        cfpkt_addbdy(pkt, physlinkid);
+       cfpkt_set_prio(pkt, TC_PRIO_CONTROL);
        dn->transmit(dn, pkt);
 }
 
@@ -281,6 +283,7 @@ int cfctrl_linkup_request(struct cflayer *layer,
         *      might arrive with the newly allocated channel ID.
         */
        cfpkt_info(pkt)->dev_info->id = param->phyid;
+       cfpkt_set_prio(pkt, TC_PRIO_CONTROL);
        ret =
            dn->transmit(dn, pkt);
        if (ret < 0) {
@@ -314,6 +317,7 @@ int cfctrl_linkdown_req(struct cflayer *layer, u8 channelid,
        cfpkt_addbdy(pkt, CFCTRL_CMD_LINK_DESTROY);
        cfpkt_addbdy(pkt, channelid);
        init_info(cfpkt_info(pkt), cfctrl);
+       cfpkt_set_prio(pkt, TC_PRIO_CONTROL);
        ret =
            dn->transmit(dn, pkt);
 #ifndef CAIF_NO_LOOP
index e335ba859b970a24d6dc785451c9b9bb8b87e2ba..863dedd91bb6b60766c3a91f0c321c29b6291afc 100644 (file)
@@ -381,6 +381,7 @@ struct cfpkt *cfpkt_split(struct cfpkt *pkt, u16 pos)
        memcpy(skb2->data, split, len2nd);
        skb2->tail += len2nd;
        skb2->len += len2nd;
+       skb2->priority = skb->priority;
        return skb_to_pkt(skb2);
 }
 
@@ -394,3 +395,9 @@ struct caif_payload_info *cfpkt_info(struct cfpkt *pkt)
        return (struct caif_payload_info *)&pkt_to_skb(pkt)->cb;
 }
 EXPORT_SYMBOL(cfpkt_info);
+
+void cfpkt_set_prio(struct cfpkt *pkt, int prio)
+{
+       pkt_to_skb(pkt)->priority = prio;
+}
+EXPORT_SYMBOL(cfpkt_set_prio);
index 4aa33d4496b681af783b1da932ee7e3c565b2ed6..dd485f6128e81df5f8b1b454f57dac3b3871158a 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/errno.h>
 #include <linux/slab.h>
 #include <linux/module.h>
+#include <linux/pkt_sched.h>
 #include <net/caif/caif_layer.h>
 #include <net/caif/cfsrvl.h>
 #include <net/caif/cfpkt.h>
@@ -120,6 +121,7 @@ static int cfservl_modemcmd(struct cflayer *layr, enum caif_modemcmd ctrl)
                        info->channel_id = service->layer.id;
                        info->hdr_len = 1;
                        info->dev_info = &service->dev_info;
+                       cfpkt_set_prio(pkt, TC_PRIO_CONTROL);
                        return layr->dn->transmit(layr->dn, pkt);
                }
        case CAIF_MODEMCMD_FLOW_OFF_REQ:
@@ -140,6 +142,7 @@ static int cfservl_modemcmd(struct cflayer *layr, enum caif_modemcmd ctrl)
                        info->channel_id = service->layer.id;
                        info->hdr_len = 1;
                        info->dev_info = &service->dev_info;
+                       cfpkt_set_prio(pkt, TC_PRIO_CONTROL);
                        return layr->dn->transmit(layr->dn, pkt);
                }
        default: