Skip to content

Commit 8d545c8

Browse files
Sjur Braendelanddavem330
authored andcommitted
caif: Disconnect without waiting for response
Changes: o Function cfcnfg_disconn_adapt_layer is changed to do asynchronous disconnect, not waiting for any response from the modem. Due to this the function cfcnfg_linkdestroy_rsp does nothing anymore. o Because disconnect may take down a connection before a connect response is received the function cfcnfg_linkup_rsp is checking if the client is still waiting for the response, if not a disconnect request is sent to the modem. o cfctrl is no longer keeping track of pending disconnect requests. o Added function cfctrl_cancel_req, which is used for deleting a pending connect request if disconnect is done before connect response is received. o Removed unused function cfctrl_insert_req2 o Added better handling of connect reject from modem. Signed-off-by: Sjur Braendeland <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 5b20865 commit 8d545c8

File tree

3 files changed

+111
-146
lines changed

3 files changed

+111
-146
lines changed

include/net/caif/cfctrl.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,7 @@ struct cfctrl_rsp {
4343
void (*linksetup_rsp)(struct cflayer *layer, u8 linkid,
4444
enum cfctrl_srv serv, u8 phyid,
4545
struct cflayer *adapt_layer);
46-
void (*linkdestroy_rsp)(struct cflayer *layer, u8 linkid,
47-
struct cflayer *client_layer);
46+
void (*linkdestroy_rsp)(struct cflayer *layer, u8 linkid);
4847
void (*linkerror_ind)(void);
4948
void (*enum_rsp)(void);
5049
void (*sleep_rsp)(void);
@@ -117,7 +116,7 @@ struct cfctrl {
117116
};
118117

119118
void cfctrl_enum_req(struct cflayer *cfctrl, u8 physlinkid);
120-
void cfctrl_linkup_request(struct cflayer *cfctrl,
119+
int cfctrl_linkup_request(struct cflayer *cfctrl,
121120
struct cfctrl_link_param *param,
122121
struct cflayer *user_layer);
123122
int cfctrl_linkdown_req(struct cflayer *cfctrl, u8 linkid,
@@ -135,4 +134,6 @@ void cfctrl_insert_req(struct cfctrl *ctrl,
135134
struct cfctrl_request_info *req);
136135
struct cfctrl_request_info *cfctrl_remove_req(struct cfctrl *ctrl,
137136
struct cfctrl_request_info *req);
137+
void cfctrl_cancel_req(struct cflayer *layr, struct cflayer *adap_layer);
138+
138139
#endif /* CFCTRL_H_ */

net/caif/cfcnfg.c

Lines changed: 45 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,7 @@ struct cfcnfg {
5454
static void cfcnfg_linkup_rsp(struct cflayer *layer, u8 channel_id,
5555
enum cfctrl_srv serv, u8 phyid,
5656
struct cflayer *adapt_layer);
57-
static void cfcnfg_linkdestroy_rsp(struct cflayer *layer, u8 channel_id,
58-
struct cflayer *client_layer);
57+
static void cfcnfg_linkdestroy_rsp(struct cflayer *layer, u8 channel_id);
5958
static void cfcnfg_reject_rsp(struct cflayer *layer, u8 channel_id,
6059
struct cflayer *adapt_layer);
6160
static void cfctrl_resp_func(void);
@@ -175,73 +174,65 @@ int cfcnfg_get_named(struct cfcnfg *cnfg, char *name)
175174
return 0;
176175
}
177176

178-
/*
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-
*/
194177
int cfcnfg_disconn_adapt_layer(struct cfcnfg *cnfg, struct cflayer *adap_layer)
195178
{
196179
u8 channel_id = 0;
197180
int ret = 0;
181+
struct cflayer *servl = NULL;
198182
struct cfcnfg_phyinfo *phyinfo = NULL;
199183
u8 phyid = 0;
200-
201184
caif_assert(adap_layer != NULL);
202185
channel_id = adap_layer->id;
203-
if (channel_id == 0) {
186+
if (adap_layer->dn == NULL || channel_id == 0) {
204187
pr_err("CAIF: %s():adap_layer->id is 0\n", __func__);
205188
ret = -ENOTCONN;
206189
goto end;
207190
}
208-
209-
if (adap_layer->dn == NULL) {
210-
pr_err("CAIF: %s():adap_layer->dn is NULL\n", __func__);
211-
ret = -ENODEV;
212-
goto end;
213-
}
214-
215-
if (adap_layer->dn != NULL)
216-
phyid = cfsrvl_getphyid(adap_layer->dn);
217-
218-
phyinfo = cfcnfg_get_phyinfo(cnfg, phyid);
219-
if (phyinfo == NULL) {
220-
pr_warning("CAIF: %s(): No interface to send disconnect to\n",
221-
__func__);
222-
ret = -ENODEV;
191+
servl = cfmuxl_remove_uplayer(cnfg->mux, channel_id);
192+
if (servl == NULL)
223193
goto end;
224-
}
225-
226-
if (phyinfo->id != phyid
227-
|| phyinfo->phy_layer->id != phyid
228-
|| phyinfo->frm_layer->id != phyid) {
229-
230-
pr_err("CAIF: %s(): Inconsistency in phy registration\n",
231-
__func__);
194+
layer_set_up(servl, NULL);
195+
ret = cfctrl_linkdown_req(cnfg->ctrl, channel_id, adap_layer);
196+
if (servl == NULL) {
197+
pr_err("CAIF: %s(): PROTOCOL ERROR "
198+
"- Error removing service_layer Channel_Id(%d)",
199+
__func__, channel_id);
232200
ret = -EINVAL;
233201
goto end;
234202
}
203+
caif_assert(channel_id == servl->id);
204+
if (adap_layer->dn != NULL) {
205+
phyid = cfsrvl_getphyid(adap_layer->dn);
235206

236-
ret = cfctrl_linkdown_req(cnfg->ctrl, channel_id, adap_layer);
237-
238-
end:
207+
phyinfo = cfcnfg_get_phyinfo(cnfg, phyid);
208+
if (phyinfo == NULL) {
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+
}
239225
if (phyinfo != NULL && --phyinfo->phy_ref_count == 0 &&
240226
phyinfo->phy_layer != NULL &&
241227
phyinfo->phy_layer->modemcmd != NULL) {
242228
phyinfo->phy_layer->modemcmd(phyinfo->phy_layer,
243229
_CAIF_MODEMCMD_PHYIF_USELESS);
244230
}
231+
end:
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);
245236
return ret;
246237

247238
}
@@ -254,69 +245,11 @@ void cfcnfg_release_adap_layer(struct cflayer *adap_layer)
254245
}
255246
EXPORT_SYMBOL(cfcnfg_release_adap_layer);
256247

257-
static void cfcnfg_linkdestroy_rsp(struct cflayer *layer, u8 channel_id,
258-
struct cflayer *client_layer)
248+
static void cfcnfg_linkdestroy_rsp(struct cflayer *layer, u8 channel_id)
259249
{
260-
struct cfcnfg *cnfg = container_obj(layer);
261-
struct cflayer *servl;
262-
263-
/*
264-
* 1) Remove service from the MUX layer. The MUX must
265-
* guarante that no more payload sent "upwards" (receive)
266-
*/
267-
servl = cfmuxl_remove_uplayer(cnfg->mux, channel_id);
268-
269-
if (servl == NULL) {
270-
pr_err("CAIF: %s(): PROTOCOL ERROR "
271-
"- Error removing service_layer Channel_Id(%d)",
272-
__func__, channel_id);
273-
return;
274-
}
275-
caif_assert(channel_id == servl->id);
276-
277-
if (servl != client_layer && servl->up != client_layer) {
278-
pr_err("CAIF: %s(): Error removing service_layer "
279-
"Channel_Id(%d) %p %p",
280-
__func__, channel_id, (void *) servl,
281-
(void *) client_layer);
282-
return;
283-
}
284-
285-
/*
286-
* 2) DEINIT_RSP must guarantee that no more packets are transmitted
287-
* from client (adap_layer) when it returns.
288-
*/
289-
290-
if (servl->ctrlcmd == NULL) {
291-
pr_err("CAIF: %s(): Error servl->ctrlcmd == NULL", __func__);
292-
return;
293-
}
294-
295-
servl->ctrlcmd(servl, CAIF_CTRLCMD_DEINIT_RSP, 0);
296-
297-
/* 3) It is now safe to destroy the service layer. */
298-
cfservl_destroy(servl);
299250
}
300251

301-
/*
302-
* NOTE: What happens on linksetup failure:
303-
* 1a) No response - Too early
304-
* This will not happen because enumerate is secured
305-
* before using interface.
306-
* 1b) No response - FATAL
307-
* Not handled, but this should be a CAIF PROTOCOL ERROR
308-
* Modem error, response is really expected - this case is
309-
* not really handled.
310-
* 2) O/E-bit indicate error
311-
* Handled in cnfg_reject_rsp
312-
* 3) Not able to match on request
313-
* Not handled, but this should be a CAIF PROTOCOL ERROR
314-
* 4) Link-Error - (no response)
315-
* Not handled, but this should be a CAIF PROTOCOL ERROR
316-
*/
317-
318-
int
319-
cfcnfg_add_adaptation_layer(struct cfcnfg *cnfg,
252+
int cfcnfg_add_adaptation_layer(struct cfcnfg *cnfg,
320253
struct cfctrl_link_param *param,
321254
struct cflayer *adap_layer)
322255
{
@@ -346,8 +279,7 @@ cfcnfg_add_adaptation_layer(struct cfcnfg *cnfg,
346279
param->phyid);
347280
/* FIXME: ENUMERATE INITIALLY WHEN ACTIVATING PHYSICAL INTERFACE */
348281
cfctrl_enum_req(cnfg->ctrl, param->phyid);
349-
cfctrl_linkup_request(cnfg->ctrl, param, adap_layer);
350-
return 0;
282+
return cfctrl_linkup_request(cnfg->ctrl, param, adap_layer);
351283
}
352284
EXPORT_SYMBOL(cfcnfg_add_adaptation_layer);
353285

@@ -367,8 +299,10 @@ cfcnfg_linkup_rsp(struct cflayer *layer, u8 channel_id, enum cfctrl_srv serv,
367299
struct cflayer *servicel = NULL;
368300
struct cfcnfg_phyinfo *phyinfo;
369301
if (adapt_layer == NULL) {
370-
pr_err("CAIF: %s(): PROTOCOL ERROR "
371-
"- LinkUp Request/Response did not match\n", __func__);
302+
pr_debug("CAIF: %s(): link setup response "
303+
"but no client exist, send linkdown back\n",
304+
__func__);
305+
cfctrl_linkdown_req(cnfg->ctrl, channel_id, NULL);
372306
return;
373307
}
374308

@@ -424,6 +358,7 @@ cfcnfg_linkup_rsp(struct cflayer *layer, u8 channel_id, enum cfctrl_srv serv,
424358
cfmuxl_set_uplayer(cnfg->mux, servicel, channel_id);
425359
layer_set_up(servicel, adapt_layer);
426360
layer_set_dn(adapt_layer, servicel);
361+
cfsrvl_get(servicel);
427362
servicel->ctrlcmd(servicel, CAIF_CTRLCMD_INIT_RSP, 0);
428363
}
429364

0 commit comments

Comments
 (0)