Blame view
net/caif/cfsrvl.c
5.51 KB
b482cd205 net-caif: add CAI... |
1 2 3 4 5 |
/* * Copyright (C) ST-Ericsson AB 2010 * Author: Sjur Brendeland/sjur.brandeland@stericsson.com * License terms: GNU General Public License (GPL) version 2 */ |
b31fa5bad net/caif: Use pr_fmt |
6 |
#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ |
b482cd205 net-caif: add CAI... |
7 8 9 10 |
#include <linux/kernel.h> #include <linux/types.h> #include <linux/errno.h> #include <linux/slab.h> |
43e369210 caif: Move refcou... |
11 |
#include <linux/module.h> |
b482cd205 net-caif: add CAI... |
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
#include <net/caif/caif_layer.h> #include <net/caif/cfsrvl.h> #include <net/caif/cfpkt.h> #define SRVL_CTRL_PKT_SIZE 1 #define SRVL_FLOW_OFF 0x81 #define SRVL_FLOW_ON 0x80 #define SRVL_SET_PIN 0x82 #define SRVL_CTRL_PKT_SIZE 1 #define container_obj(layr) container_of(layr, struct cfsrvl, layer) static void cfservl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, int phyid) { struct cfsrvl *service = container_obj(layr); |
b1c74247b caif: Bugfix not ... |
28 |
|
43e369210 caif: Move refcou... |
29 30 |
if (layr->up == NULL || layr->up->ctrlcmd == NULL) return; |
b1c74247b caif: Bugfix not ... |
31 |
|
b482cd205 net-caif: add CAI... |
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
switch (ctrl) { case CAIF_CTRLCMD_INIT_RSP: service->open = true; layr->up->ctrlcmd(layr->up, ctrl, phyid); break; case CAIF_CTRLCMD_DEINIT_RSP: case CAIF_CTRLCMD_INIT_FAIL_RSP: service->open = false; layr->up->ctrlcmd(layr->up, ctrl, phyid); break; case _CAIF_CTRLCMD_PHYIF_FLOW_OFF_IND: if (phyid != service->dev_info.id) break; if (service->modem_flow_on) layr->up->ctrlcmd(layr->up, CAIF_CTRLCMD_FLOW_OFF_IND, phyid); service->phy_flow_on = false; break; case _CAIF_CTRLCMD_PHYIF_FLOW_ON_IND: if (phyid != service->dev_info.id) return; if (service->modem_flow_on) { layr->up->ctrlcmd(layr->up, CAIF_CTRLCMD_FLOW_ON_IND, phyid); } service->phy_flow_on = true; break; case CAIF_CTRLCMD_FLOW_OFF_IND: if (service->phy_flow_on) { layr->up->ctrlcmd(layr->up, CAIF_CTRLCMD_FLOW_OFF_IND, phyid); } service->modem_flow_on = false; break; case CAIF_CTRLCMD_FLOW_ON_IND: if (service->phy_flow_on) { layr->up->ctrlcmd(layr->up, CAIF_CTRLCMD_FLOW_ON_IND, phyid); } service->modem_flow_on = true; break; case _CAIF_CTRLCMD_PHYIF_DOWN_IND: /* In case interface is down, let's fake a remove shutdown */ layr->up->ctrlcmd(layr->up, CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND, phyid); break; case CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND: layr->up->ctrlcmd(layr->up, ctrl, phyid); break; default: |
b31fa5bad net/caif: Use pr_fmt |
83 84 |
pr_warn("Unexpected ctrl in cfsrvl (%d) ", ctrl); |
b482cd205 net-caif: add CAI... |
85 86 87 88 89 90 91 92 93 94 |
/* We have both modem and phy flow on, send flow on */ layr->up->ctrlcmd(layr->up, ctrl, phyid); service->phy_flow_on = true; break; } } static int cfservl_modemcmd(struct cflayer *layr, enum caif_modemcmd ctrl) { struct cfsrvl *service = container_obj(layr); |
b1c74247b caif: Bugfix not ... |
95 |
|
b482cd205 net-caif: add CAI... |
96 97 98 |
caif_assert(layr != NULL); caif_assert(layr->dn != NULL); caif_assert(layr->dn->transmit != NULL); |
b1c74247b caif: Bugfix not ... |
99 100 101 |
if (!service->supports_flowctrl) return 0; |
b482cd205 net-caif: add CAI... |
102 103 104 105 106 107 108 |
switch (ctrl) { case CAIF_MODEMCMD_FLOW_ON_REQ: { struct cfpkt *pkt; struct caif_payload_info *info; u8 flow_on = SRVL_FLOW_ON; pkt = cfpkt_create(SRVL_CTRL_PKT_SIZE); |
7ac2ed0ce caif: Remove OOM ... |
109 |
if (!pkt) |
b482cd205 net-caif: add CAI... |
110 |
return -ENOMEM; |
b482cd205 net-caif: add CAI... |
111 112 |
if (cfpkt_add_head(pkt, &flow_on, 1) < 0) { |
b31fa5bad net/caif: Use pr_fmt |
113 114 |
pr_err("Packet is erroneous! "); |
b482cd205 net-caif: add CAI... |
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
cfpkt_destroy(pkt); return -EPROTO; } info = cfpkt_info(pkt); info->channel_id = service->layer.id; info->hdr_len = 1; info->dev_info = &service->dev_info; return layr->dn->transmit(layr->dn, pkt); } case CAIF_MODEMCMD_FLOW_OFF_REQ: { struct cfpkt *pkt; struct caif_payload_info *info; u8 flow_off = SRVL_FLOW_OFF; pkt = cfpkt_create(SRVL_CTRL_PKT_SIZE); |
7ac2ed0ce caif: Remove OOM ... |
130 |
if (!pkt) |
638e628a6 caif: Bugfix - ha... |
131 |
return -ENOMEM; |
638e628a6 caif: Bugfix - ha... |
132 |
|
b482cd205 net-caif: add CAI... |
133 |
if (cfpkt_add_head(pkt, &flow_off, 1) < 0) { |
b31fa5bad net/caif: Use pr_fmt |
134 135 |
pr_err("Packet is erroneous! "); |
b482cd205 net-caif: add CAI... |
136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
cfpkt_destroy(pkt); return -EPROTO; } info = cfpkt_info(pkt); info->channel_id = service->layer.id; info->hdr_len = 1; info->dev_info = &service->dev_info; return layr->dn->transmit(layr->dn, pkt); } default: break; } return -EINVAL; } |
43e369210 caif: Move refcou... |
150 |
static void cfsrvl_release(struct cflayer *layer) |
a7da1f55a caif: Bugfix - RF... |
151 |
{ |
43e369210 caif: Move refcou... |
152 |
struct cfsrvl *service = container_of(layer, struct cfsrvl, layer); |
a7da1f55a caif: Bugfix - RF... |
153 154 |
kfree(service); } |
b482cd205 net-caif: add CAI... |
155 |
void cfsrvl_init(struct cfsrvl *service, |
b1c74247b caif: Bugfix not ... |
156 157 158 159 |
u8 channel_id, struct dev_info *dev_info, bool supports_flowctrl ) |
b482cd205 net-caif: add CAI... |
160 161 162 163 164 165 166 167 168 |
{ caif_assert(offsetof(struct cfsrvl, layer) == 0); service->open = false; service->modem_flow_on = true; service->phy_flow_on = true; service->layer.id = channel_id; service->layer.ctrlcmd = cfservl_ctrlcmd; service->layer.modemcmd = cfservl_modemcmd; service->dev_info = *dev_info; |
b1c74247b caif: Bugfix not ... |
169 |
service->supports_flowctrl = supports_flowctrl; |
a7da1f55a caif: Bugfix - RF... |
170 |
service->release = cfsrvl_release; |
5b2086567 caif: Add referen... |
171 |
} |
b482cd205 net-caif: add CAI... |
172 173 174 175 176 177 178 179 180 181 182 183 |
bool cfsrvl_ready(struct cfsrvl *service, int *err) { if (service->open && service->modem_flow_on && service->phy_flow_on) return true; if (!service->open) { *err = -ENOTCONN; return false; } caif_assert(!(service->modem_flow_on && service->phy_flow_on)); *err = -EAGAIN; return false; } |
43e369210 caif: Move refcou... |
184 |
|
b482cd205 net-caif: add CAI... |
185 186 187 188 189 190 191 192 193 194 195 |
u8 cfsrvl_getphyid(struct cflayer *layer) { struct cfsrvl *servl = container_obj(layer); return servl->dev_info.id; } bool cfsrvl_phyid_match(struct cflayer *layer, int phyid) { struct cfsrvl *servl = container_obj(layer); return servl->dev_info.id == phyid; } |
43e369210 caif: Move refcou... |
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 |
void caif_free_client(struct cflayer *adap_layer) { struct cfsrvl *servl; if (adap_layer == NULL || adap_layer->dn == NULL) return; servl = container_obj(adap_layer->dn); servl->release(&servl->layer); } EXPORT_SYMBOL(caif_free_client); void caif_client_register_refcnt(struct cflayer *adapt_layer, void (*hold)(struct cflayer *lyr), void (*put)(struct cflayer *lyr)) { struct cfsrvl *service; service = container_of(adapt_layer->dn, struct cfsrvl, layer); WARN_ON(adapt_layer == NULL || adapt_layer->dn == NULL); service->hold = hold; service->put = put; } EXPORT_SYMBOL(caif_client_register_refcnt); |