diff options
Diffstat (limited to 'net/caif/cfcnfg.c')
| -rw-r--r-- | net/caif/cfcnfg.c | 54 |
1 files changed, 44 insertions, 10 deletions
diff --git a/net/caif/cfcnfg.c b/net/caif/cfcnfg.c index df43f264d9fb..1c29189b344d 100644 --- a/net/caif/cfcnfg.c +++ b/net/caif/cfcnfg.c | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | #include <linux/kernel.h> | 6 | #include <linux/kernel.h> |
| 7 | #include <linux/stddef.h> | 7 | #include <linux/stddef.h> |
| 8 | #include <linux/slab.h> | 8 | #include <linux/slab.h> |
| 9 | #include <linux/netdevice.h> | ||
| 9 | #include <net/caif/caif_layer.h> | 10 | #include <net/caif/caif_layer.h> |
| 10 | #include <net/caif/cfpkt.h> | 11 | #include <net/caif/cfpkt.h> |
| 11 | #include <net/caif/cfcnfg.h> | 12 | #include <net/caif/cfcnfg.h> |
| @@ -22,6 +23,7 @@ | |||
| 22 | #define PHY_NAME_LEN 20 | 23 | #define PHY_NAME_LEN 20 |
| 23 | 24 | ||
| 24 | #define container_obj(layr) container_of(layr, struct cfcnfg, layer) | 25 | #define container_obj(layr) container_of(layr, struct cfcnfg, layer) |
| 26 | #define RFM_FRAGMENT_SIZE 4030 | ||
| 25 | 27 | ||
| 26 | /* Information about CAIF physical interfaces held by Config Module in order | 28 | /* Information about CAIF physical interfaces held by Config Module in order |
| 27 | * to manage physical interfaces | 29 | * to manage physical interfaces |
| @@ -41,6 +43,15 @@ struct cfcnfg_phyinfo { | |||
| 41 | 43 | ||
| 42 | /* Information about the physical device */ | 44 | /* Information about the physical device */ |
| 43 | struct dev_info dev_info; | 45 | struct dev_info dev_info; |
| 46 | |||
| 47 | /* Interface index */ | ||
| 48 | int ifindex; | ||
| 49 | |||
| 50 | /* Use Start of frame extension */ | ||
| 51 | bool use_stx; | ||
| 52 | |||
| 53 | /* Use Start of frame checksum */ | ||
| 54 | bool use_fcs; | ||
| 44 | }; | 55 | }; |
| 45 | 56 | ||
| 46 | struct cfcnfg { | 57 | struct cfcnfg { |
| @@ -248,9 +259,20 @@ static void cfcnfg_linkdestroy_rsp(struct cflayer *layer, u8 channel_id) | |||
| 248 | { | 259 | { |
| 249 | } | 260 | } |
| 250 | 261 | ||
| 262 | int protohead[CFCTRL_SRV_MASK] = { | ||
| 263 | [CFCTRL_SRV_VEI] = 4, | ||
| 264 | [CFCTRL_SRV_DATAGRAM] = 7, | ||
| 265 | [CFCTRL_SRV_UTIL] = 4, | ||
| 266 | [CFCTRL_SRV_RFM] = 3, | ||
| 267 | [CFCTRL_SRV_DBG] = 3, | ||
| 268 | }; | ||
| 269 | |||
| 251 | int cfcnfg_add_adaptation_layer(struct cfcnfg *cnfg, | 270 | int cfcnfg_add_adaptation_layer(struct cfcnfg *cnfg, |
| 252 | struct cfctrl_link_param *param, | 271 | struct cfctrl_link_param *param, |
| 253 | struct cflayer *adap_layer) | 272 | struct cflayer *adap_layer, |
| 273 | int *ifindex, | ||
| 274 | int *proto_head, | ||
| 275 | int *proto_tail) | ||
| 254 | { | 276 | { |
| 255 | struct cflayer *frml; | 277 | struct cflayer *frml; |
| 256 | if (adap_layer == NULL) { | 278 | if (adap_layer == NULL) { |
| @@ -276,6 +298,14 @@ int cfcnfg_add_adaptation_layer(struct cfcnfg *cnfg, | |||
| 276 | param->phyid); | 298 | param->phyid); |
| 277 | caif_assert(cnfg->phy_layers[param->phyid].phy_layer->id == | 299 | caif_assert(cnfg->phy_layers[param->phyid].phy_layer->id == |
| 278 | param->phyid); | 300 | param->phyid); |
| 301 | |||
| 302 | *ifindex = cnfg->phy_layers[param->phyid].ifindex; | ||
| 303 | *proto_head = | ||
| 304 | protohead[param->linktype]+ | ||
| 305 | (cnfg->phy_layers[param->phyid].use_stx ? 1 : 0); | ||
| 306 | |||
| 307 | *proto_tail = 2; | ||
| 308 | |||
| 279 | /* FIXME: ENUMERATE INITIALLY WHEN ACTIVATING PHYSICAL INTERFACE */ | 309 | /* FIXME: ENUMERATE INITIALLY WHEN ACTIVATING PHYSICAL INTERFACE */ |
| 280 | cfctrl_enum_req(cnfg->ctrl, param->phyid); | 310 | cfctrl_enum_req(cnfg->ctrl, param->phyid); |
| 281 | return cfctrl_linkup_request(cnfg->ctrl, param, adap_layer); | 311 | return cfctrl_linkup_request(cnfg->ctrl, param, adap_layer); |
| @@ -297,6 +327,8 @@ cfcnfg_linkup_rsp(struct cflayer *layer, u8 channel_id, enum cfctrl_srv serv, | |||
| 297 | struct cfcnfg *cnfg = container_obj(layer); | 327 | struct cfcnfg *cnfg = container_obj(layer); |
| 298 | struct cflayer *servicel = NULL; | 328 | struct cflayer *servicel = NULL; |
| 299 | struct cfcnfg_phyinfo *phyinfo; | 329 | struct cfcnfg_phyinfo *phyinfo; |
| 330 | struct net_device *netdev; | ||
| 331 | |||
| 300 | if (adapt_layer == NULL) { | 332 | if (adapt_layer == NULL) { |
| 301 | pr_debug("CAIF: %s(): link setup response " | 333 | pr_debug("CAIF: %s(): link setup response " |
| 302 | "but no client exist, send linkdown back\n", | 334 | "but no client exist, send linkdown back\n", |
| @@ -308,19 +340,15 @@ cfcnfg_linkup_rsp(struct cflayer *layer, u8 channel_id, enum cfctrl_srv serv, | |||
| 308 | caif_assert(cnfg != NULL); | 340 | caif_assert(cnfg != NULL); |
| 309 | caif_assert(phyid != 0); | 341 | caif_assert(phyid != 0); |
| 310 | phyinfo = &cnfg->phy_layers[phyid]; | 342 | phyinfo = &cnfg->phy_layers[phyid]; |
| 311 | caif_assert(phyinfo != NULL); | ||
| 312 | caif_assert(phyinfo->id == phyid); | 343 | caif_assert(phyinfo->id == phyid); |
| 313 | caif_assert(phyinfo->phy_layer != NULL); | 344 | caif_assert(phyinfo->phy_layer != NULL); |
| 314 | caif_assert(phyinfo->phy_layer->id == phyid); | 345 | caif_assert(phyinfo->phy_layer->id == phyid); |
| 315 | 346 | ||
| 316 | if (phyinfo != NULL && | 347 | phyinfo->phy_ref_count++; |
| 317 | phyinfo->phy_ref_count++ == 0 && | 348 | if (phyinfo->phy_ref_count == 1 && |
| 318 | phyinfo->phy_layer != NULL && | ||
| 319 | phyinfo->phy_layer->modemcmd != NULL) { | 349 | phyinfo->phy_layer->modemcmd != NULL) { |
| 320 | caif_assert(phyinfo->phy_layer->id == phyid); | ||
| 321 | phyinfo->phy_layer->modemcmd(phyinfo->phy_layer, | 350 | phyinfo->phy_layer->modemcmd(phyinfo->phy_layer, |
| 322 | _CAIF_MODEMCMD_PHYIF_USEFULL); | 351 | _CAIF_MODEMCMD_PHYIF_USEFULL); |
| 323 | |||
| 324 | } | 352 | } |
| 325 | adapt_layer->id = channel_id; | 353 | adapt_layer->id = channel_id; |
| 326 | 354 | ||
| @@ -332,7 +360,9 @@ cfcnfg_linkup_rsp(struct cflayer *layer, u8 channel_id, enum cfctrl_srv serv, | |||
| 332 | servicel = cfdgml_create(channel_id, &phyinfo->dev_info); | 360 | servicel = cfdgml_create(channel_id, &phyinfo->dev_info); |
| 333 | break; | 361 | break; |
| 334 | case CFCTRL_SRV_RFM: | 362 | case CFCTRL_SRV_RFM: |
| 335 | servicel = cfrfml_create(channel_id, &phyinfo->dev_info); | 363 | netdev = phyinfo->dev_info.dev; |
| 364 | servicel = cfrfml_create(channel_id, &phyinfo->dev_info, | ||
| 365 | netdev->mtu); | ||
| 336 | break; | 366 | break; |
| 337 | case CFCTRL_SRV_UTIL: | 367 | case CFCTRL_SRV_UTIL: |
| 338 | servicel = cfutill_create(channel_id, &phyinfo->dev_info); | 368 | servicel = cfutill_create(channel_id, &phyinfo->dev_info); |
| @@ -363,8 +393,8 @@ cfcnfg_linkup_rsp(struct cflayer *layer, u8 channel_id, enum cfctrl_srv serv, | |||
| 363 | 393 | ||
| 364 | void | 394 | void |
| 365 | cfcnfg_add_phy_layer(struct cfcnfg *cnfg, enum cfcnfg_phy_type phy_type, | 395 | cfcnfg_add_phy_layer(struct cfcnfg *cnfg, enum cfcnfg_phy_type phy_type, |
| 366 | void *dev, struct cflayer *phy_layer, u16 *phyid, | 396 | struct net_device *dev, struct cflayer *phy_layer, |
| 367 | enum cfcnfg_phy_preference pref, | 397 | u16 *phyid, enum cfcnfg_phy_preference pref, |
| 368 | bool fcs, bool stx) | 398 | bool fcs, bool stx) |
| 369 | { | 399 | { |
| 370 | struct cflayer *frml; | 400 | struct cflayer *frml; |
| @@ -418,6 +448,10 @@ cfcnfg_add_phy_layer(struct cfcnfg *cnfg, enum cfcnfg_phy_type phy_type, | |||
| 418 | cnfg->phy_layers[*phyid].dev_info.dev = dev; | 448 | cnfg->phy_layers[*phyid].dev_info.dev = dev; |
| 419 | cnfg->phy_layers[*phyid].phy_layer = phy_layer; | 449 | cnfg->phy_layers[*phyid].phy_layer = phy_layer; |
| 420 | cnfg->phy_layers[*phyid].phy_ref_count = 0; | 450 | cnfg->phy_layers[*phyid].phy_ref_count = 0; |
| 451 | cnfg->phy_layers[*phyid].ifindex = dev->ifindex; | ||
| 452 | cnfg->phy_layers[*phyid].use_stx = stx; | ||
| 453 | cnfg->phy_layers[*phyid].use_fcs = fcs; | ||
| 454 | |||
| 421 | phy_layer->type = phy_type; | 455 | phy_layer->type = phy_type; |
| 422 | frml = cffrml_create(*phyid, fcs); | 456 | frml = cffrml_create(*phyid, fcs); |
| 423 | if (!frml) { | 457 | if (!frml) { |
