aboutsummaryrefslogtreecommitdiffstats
path: root/net/caif/cfcnfg.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/caif/cfcnfg.c')
-rw-r--r--net/caif/cfcnfg.c195
1 files changed, 68 insertions, 127 deletions
diff --git a/net/caif/cfcnfg.c b/net/caif/cfcnfg.c
index c873e3d4387c..471c62939fad 100644
--- a/net/caif/cfcnfg.c
+++ b/net/caif/cfcnfg.c
@@ -51,12 +51,11 @@ struct cfcnfg {
51 struct cfcnfg_phyinfo phy_layers[MAX_PHY_LAYERS]; 51 struct cfcnfg_phyinfo phy_layers[MAX_PHY_LAYERS];
52}; 52};
53 53
54static void cncfg_linkup_rsp(struct cflayer *layer, u8 linkid, 54static void cfcnfg_linkup_rsp(struct cflayer *layer, u8 channel_id,
55 enum cfctrl_srv serv, u8 phyid, 55 enum cfctrl_srv serv, u8 phyid,
56 struct cflayer *adapt_layer); 56 struct cflayer *adapt_layer);
57static void cncfg_linkdestroy_rsp(struct cflayer *layer, u8 linkid, 57static void cfcnfg_linkdestroy_rsp(struct cflayer *layer, u8 channel_id);
58 struct cflayer *client_layer); 58static void cfcnfg_reject_rsp(struct cflayer *layer, u8 channel_id,
59static void cncfg_reject_rsp(struct cflayer *layer, u8 linkid,
60 struct cflayer *adapt_layer); 59 struct cflayer *adapt_layer);
61static void cfctrl_resp_func(void); 60static void cfctrl_resp_func(void);
62static void cfctrl_enum_resp(void); 61static void cfctrl_enum_resp(void);
@@ -82,13 +81,13 @@ struct cfcnfg *cfcnfg_create(void)
82 resp = cfctrl_get_respfuncs(this->ctrl); 81 resp = cfctrl_get_respfuncs(this->ctrl);
83 resp->enum_rsp = cfctrl_enum_resp; 82 resp->enum_rsp = cfctrl_enum_resp;
84 resp->linkerror_ind = cfctrl_resp_func; 83 resp->linkerror_ind = cfctrl_resp_func;
85 resp->linkdestroy_rsp = cncfg_linkdestroy_rsp; 84 resp->linkdestroy_rsp = cfcnfg_linkdestroy_rsp;
86 resp->sleep_rsp = cfctrl_resp_func; 85 resp->sleep_rsp = cfctrl_resp_func;
87 resp->wake_rsp = cfctrl_resp_func; 86 resp->wake_rsp = cfctrl_resp_func;
88 resp->restart_rsp = cfctrl_resp_func; 87 resp->restart_rsp = cfctrl_resp_func;
89 resp->radioset_rsp = cfctrl_resp_func; 88 resp->radioset_rsp = cfctrl_resp_func;
90 resp->linksetup_rsp = cncfg_linkup_rsp; 89 resp->linksetup_rsp = cfcnfg_linkup_rsp;
91 resp->reject_rsp = cncfg_reject_rsp; 90 resp->reject_rsp = cfcnfg_reject_rsp;
92 91
93 this->last_phyid = 1; 92 this->last_phyid = 1;
94 93
@@ -175,142 +174,82 @@ int cfcnfg_get_named(struct cfcnfg *cnfg, char *name)
175 return 0; 174 return 0;
176} 175}
177 176
178/* 177int cfcnfg_disconn_adapt_layer(struct cfcnfg *cnfg, struct cflayer *adap_layer)
179 * NOTE: What happens on destroy failure:
180 * 1a) No response - Too early
181 * This will not happen because enumerate has already
182 * completed.
183 * 1b) No response - FATAL
184 * Not handled, but this should be a CAIF PROTOCOL ERROR
185 * Modem error, response is really expected - this
186 * case is not really handled.
187 * 2) O/E-bit indicate error
188 * Ignored - this link is destroyed anyway.
189 * 3) Not able to match on request
190 * Not handled, but this should be a CAIF PROTOCOL ERROR
191 * 4) Link-Error - (no response)
192 * Not handled, but this should be a CAIF PROTOCOL ERROR
193 */
194
195int cfcnfg_del_adapt_layer(struct cfcnfg *cnfg, struct cflayer *adap_layer)
196{ 178{
197 u8 channel_id = 0; 179 u8 channel_id = 0;
198 int ret = 0; 180 int ret = 0;
181 struct cflayer *servl = NULL;
199 struct cfcnfg_phyinfo *phyinfo = NULL; 182 struct cfcnfg_phyinfo *phyinfo = NULL;
200 u8 phyid = 0; 183 u8 phyid = 0;
201
202 caif_assert(adap_layer != NULL); 184 caif_assert(adap_layer != NULL);
203 channel_id = adap_layer->id; 185 channel_id = adap_layer->id;
204 if (channel_id == 0) { 186 if (adap_layer->dn == NULL || channel_id == 0) {
205 pr_err("CAIF: %s():adap_layer->id is 0\n", __func__); 187 pr_err("CAIF: %s():adap_layer->id is 0\n", __func__);
206 ret = -ENOTCONN; 188 ret = -ENOTCONN;
207 goto end; 189 goto end;
208 } 190 }
209 191 servl = cfmuxl_remove_uplayer(cnfg->mux, channel_id);
210 if (adap_layer->dn == NULL) { 192 if (servl == NULL)
211 pr_err("CAIF: %s():adap_layer->dn is NULL\n", __func__);
212 ret = -ENODEV;
213 goto end;
214 }
215
216 if (adap_layer->dn != NULL)
217 phyid = cfsrvl_getphyid(adap_layer->dn);
218
219 phyinfo = cfcnfg_get_phyinfo(cnfg, phyid);
220 if (phyinfo == NULL) {
221 pr_warning("CAIF: %s(): No interface to send disconnect to\n",
222 __func__);
223 ret = -ENODEV;
224 goto end; 193 goto end;
225 } 194 layer_set_up(servl, NULL);
226 195 ret = cfctrl_linkdown_req(cnfg->ctrl, channel_id, adap_layer);
227 if (phyinfo->id != phyid 196 if (servl == NULL) {
228 || phyinfo->phy_layer->id != phyid 197 pr_err("CAIF: %s(): PROTOCOL ERROR "
229 || phyinfo->frm_layer->id != phyid) { 198 "- Error removing service_layer Channel_Id(%d)",
230 199 __func__, channel_id);
231 pr_err("CAIF: %s(): Inconsistency in phy registration\n",
232 __func__);
233 ret = -EINVAL; 200 ret = -EINVAL;
234 goto end; 201 goto end;
235 } 202 }
203 caif_assert(channel_id == servl->id);
204 if (adap_layer->dn != NULL) {
205 phyid = cfsrvl_getphyid(adap_layer->dn);
236 206
237 ret = cfctrl_linkdown_req(cnfg->ctrl, channel_id, adap_layer); 207 phyinfo = cfcnfg_get_phyinfo(cnfg, phyid);
238 208 if (phyinfo == NULL) {
239end: 209 pr_warning("CAIF: %s(): "
210 "No interface to send disconnect to\n",
211 __func__);
212 ret = -ENODEV;
213 goto end;
214 }
215 if (phyinfo->id != phyid ||
216 phyinfo->phy_layer->id != phyid ||
217 phyinfo->frm_layer->id != phyid) {
218 pr_err("CAIF: %s(): "
219 "Inconsistency in phy registration\n",
220 __func__);
221 ret = -EINVAL;
222 goto end;
223 }
224 }
240 if (phyinfo != NULL && --phyinfo->phy_ref_count == 0 && 225 if (phyinfo != NULL && --phyinfo->phy_ref_count == 0 &&
241 phyinfo->phy_layer != NULL && 226 phyinfo->phy_layer != NULL &&
242 phyinfo->phy_layer->modemcmd != NULL) { 227 phyinfo->phy_layer->modemcmd != NULL) {
243 phyinfo->phy_layer->modemcmd(phyinfo->phy_layer, 228 phyinfo->phy_layer->modemcmd(phyinfo->phy_layer,
244 _CAIF_MODEMCMD_PHYIF_USELESS); 229 _CAIF_MODEMCMD_PHYIF_USELESS);
245 } 230 }
231end:
232 cfsrvl_put(servl);
233 cfctrl_cancel_req(cnfg->ctrl, adap_layer);
234 if (adap_layer->ctrlcmd != NULL)
235 adap_layer->ctrlcmd(adap_layer, CAIF_CTRLCMD_DEINIT_RSP, 0);
246 return ret; 236 return ret;
247 237
248} 238}
249EXPORT_SYMBOL(cfcnfg_del_adapt_layer); 239EXPORT_SYMBOL(cfcnfg_disconn_adapt_layer);
250 240
251static void cncfg_linkdestroy_rsp(struct cflayer *layer, u8 linkid, 241void cfcnfg_release_adap_layer(struct cflayer *adap_layer)
252 struct cflayer *client_layer)
253{ 242{
254 struct cfcnfg *cnfg = container_obj(layer); 243 if (adap_layer->dn)
255 struct cflayer *servl; 244 cfsrvl_put(adap_layer->dn);
256
257 /*
258 * 1) Remove service from the MUX layer. The MUX must
259 * guarante that no more payload sent "upwards" (receive)
260 */
261 servl = cfmuxl_remove_uplayer(cnfg->mux, linkid);
262
263 if (servl == NULL) {
264 pr_err("CAIF: %s(): PROTOCOL ERROR "
265 "- Error removing service_layer Linkid(%d)",
266 __func__, linkid);
267 return;
268 }
269 caif_assert(linkid == servl->id);
270
271 if (servl != client_layer && servl->up != client_layer) {
272 pr_err("CAIF: %s(): Error removing service_layer "
273 "Linkid(%d) %p %p",
274 __func__, linkid, (void *) servl,
275 (void *) client_layer);
276 return;
277 }
278
279 /*
280 * 2) DEINIT_RSP must guarantee that no more packets are transmitted
281 * from client (adap_layer) when it returns.
282 */
283
284 if (servl->ctrlcmd == NULL) {
285 pr_err("CAIF: %s(): Error servl->ctrlcmd == NULL", __func__);
286 return;
287 }
288
289 servl->ctrlcmd(servl, CAIF_CTRLCMD_DEINIT_RSP, 0);
290
291 /* 3) It is now safe to destroy the service layer. */
292 cfservl_destroy(servl);
293} 245}
246EXPORT_SYMBOL(cfcnfg_release_adap_layer);
294 247
295/* 248static void cfcnfg_linkdestroy_rsp(struct cflayer *layer, u8 channel_id)
296 * NOTE: What happens on linksetup failure: 249{
297 * 1a) No response - Too early 250}
298 * This will not happen because enumerate is secured
299 * before using interface.
300 * 1b) No response - FATAL
301 * Not handled, but this should be a CAIF PROTOCOL ERROR
302 * Modem error, response is really expected - this case is
303 * not really handled.
304 * 2) O/E-bit indicate error
305 * Handled in cnfg_reject_rsp
306 * 3) Not able to match on request
307 * Not handled, but this should be a CAIF PROTOCOL ERROR
308 * 4) Link-Error - (no response)
309 * Not handled, but this should be a CAIF PROTOCOL ERROR
310 */
311 251
312int 252int cfcnfg_add_adaptation_layer(struct cfcnfg *cnfg,
313cfcnfg_add_adaptation_layer(struct cfcnfg *cnfg,
314 struct cfctrl_link_param *param, 253 struct cfctrl_link_param *param,
315 struct cflayer *adap_layer) 254 struct cflayer *adap_layer)
316{ 255{
@@ -340,12 +279,11 @@ cfcnfg_add_adaptation_layer(struct cfcnfg *cnfg,
340 param->phyid); 279 param->phyid);
341 /* FIXME: ENUMERATE INITIALLY WHEN ACTIVATING PHYSICAL INTERFACE */ 280 /* FIXME: ENUMERATE INITIALLY WHEN ACTIVATING PHYSICAL INTERFACE */
342 cfctrl_enum_req(cnfg->ctrl, param->phyid); 281 cfctrl_enum_req(cnfg->ctrl, param->phyid);
343 cfctrl_linkup_request(cnfg->ctrl, param, adap_layer); 282 return cfctrl_linkup_request(cnfg->ctrl, param, adap_layer);
344 return 0;
345} 283}
346EXPORT_SYMBOL(cfcnfg_add_adaptation_layer); 284EXPORT_SYMBOL(cfcnfg_add_adaptation_layer);
347 285
348static void cncfg_reject_rsp(struct cflayer *layer, u8 linkid, 286static void cfcnfg_reject_rsp(struct cflayer *layer, u8 channel_id,
349 struct cflayer *adapt_layer) 287 struct cflayer *adapt_layer)
350{ 288{
351 if (adapt_layer != NULL && adapt_layer->ctrlcmd != NULL) 289 if (adapt_layer != NULL && adapt_layer->ctrlcmd != NULL)
@@ -354,15 +292,17 @@ static void cncfg_reject_rsp(struct cflayer *layer, u8 linkid,
354} 292}
355 293
356static void 294static void
357cncfg_linkup_rsp(struct cflayer *layer, u8 linkid, enum cfctrl_srv serv, 295cfcnfg_linkup_rsp(struct cflayer *layer, u8 channel_id, enum cfctrl_srv serv,
358 u8 phyid, struct cflayer *adapt_layer) 296 u8 phyid, struct cflayer *adapt_layer)
359{ 297{
360 struct cfcnfg *cnfg = container_obj(layer); 298 struct cfcnfg *cnfg = container_obj(layer);
361 struct cflayer *servicel = NULL; 299 struct cflayer *servicel = NULL;
362 struct cfcnfg_phyinfo *phyinfo; 300 struct cfcnfg_phyinfo *phyinfo;
363 if (adapt_layer == NULL) { 301 if (adapt_layer == NULL) {
364 pr_err("CAIF: %s(): PROTOCOL ERROR " 302 pr_debug("CAIF: %s(): link setup response "
365 "- LinkUp Request/Response did not match\n", __func__); 303 "but no client exist, send linkdown back\n",
304 __func__);
305 cfctrl_linkdown_req(cnfg->ctrl, channel_id, NULL);
366 return; 306 return;
367 } 307 }
368 308
@@ -383,26 +323,26 @@ cncfg_linkup_rsp(struct cflayer *layer, u8 linkid, enum cfctrl_srv serv,
383 _CAIF_MODEMCMD_PHYIF_USEFULL); 323 _CAIF_MODEMCMD_PHYIF_USEFULL);
384 324
385 } 325 }
386 adapt_layer->id = linkid; 326 adapt_layer->id = channel_id;
387 327
388 switch (serv) { 328 switch (serv) {
389 case CFCTRL_SRV_VEI: 329 case CFCTRL_SRV_VEI:
390 servicel = cfvei_create(linkid, &phyinfo->dev_info); 330 servicel = cfvei_create(channel_id, &phyinfo->dev_info);
391 break; 331 break;
392 case CFCTRL_SRV_DATAGRAM: 332 case CFCTRL_SRV_DATAGRAM:
393 servicel = cfdgml_create(linkid, &phyinfo->dev_info); 333 servicel = cfdgml_create(channel_id, &phyinfo->dev_info);
394 break; 334 break;
395 case CFCTRL_SRV_RFM: 335 case CFCTRL_SRV_RFM:
396 servicel = cfrfml_create(linkid, &phyinfo->dev_info); 336 servicel = cfrfml_create(channel_id, &phyinfo->dev_info);
397 break; 337 break;
398 case CFCTRL_SRV_UTIL: 338 case CFCTRL_SRV_UTIL:
399 servicel = cfutill_create(linkid, &phyinfo->dev_info); 339 servicel = cfutill_create(channel_id, &phyinfo->dev_info);
400 break; 340 break;
401 case CFCTRL_SRV_VIDEO: 341 case CFCTRL_SRV_VIDEO:
402 servicel = cfvidl_create(linkid, &phyinfo->dev_info); 342 servicel = cfvidl_create(channel_id, &phyinfo->dev_info);
403 break; 343 break;
404 case CFCTRL_SRV_DBG: 344 case CFCTRL_SRV_DBG:
405 servicel = cfdbgl_create(linkid, &phyinfo->dev_info); 345 servicel = cfdbgl_create(channel_id, &phyinfo->dev_info);
406 break; 346 break;
407 default: 347 default:
408 pr_err("CAIF: %s(): Protocol error. " 348 pr_err("CAIF: %s(): Protocol error. "
@@ -415,9 +355,10 @@ cncfg_linkup_rsp(struct cflayer *layer, u8 linkid, enum cfctrl_srv serv,
415 return; 355 return;
416 } 356 }
417 layer_set_dn(servicel, cnfg->mux); 357 layer_set_dn(servicel, cnfg->mux);
418 cfmuxl_set_uplayer(cnfg->mux, servicel, linkid); 358 cfmuxl_set_uplayer(cnfg->mux, servicel, channel_id);
419 layer_set_up(servicel, adapt_layer); 359 layer_set_up(servicel, adapt_layer);
420 layer_set_dn(adapt_layer, servicel); 360 layer_set_dn(adapt_layer, servicel);
361 cfsrvl_get(servicel);
421 servicel->ctrlcmd(servicel, CAIF_CTRLCMD_INIT_RSP, 0); 362 servicel->ctrlcmd(servicel, CAIF_CTRLCMD_INIT_RSP, 0);
422} 363}
423 364