static void brcmf_c_pktfilter_offload_set(struct brcmf_if *ifp, char *arg) { struct brcmf_pkt_filter_le *pkt_filter; unsigned long res; int buf_len; s32 err; u32 mask_size; u32 pattern_size; char *argv[8], *buf = NULL; int i = 0; char *arg_save = NULL, *arg_org = NULL; arg_save = kstrdup(arg, GFP_ATOMIC); if (!arg_save) goto fail; arg_org = arg_save; buf = kmalloc(PKTFILTER_BUF_SIZE, GFP_ATOMIC); if (!buf) goto fail; argv[i] = strsep(&arg_save, " "); while (argv[i]) { i++; if (i >= 8) { brcmf_err("Too many parameters\n"); goto fail; } argv[i] = strsep(&arg_save, " "); } if (i != 6) { brcmf_err("Not enough args provided %d\n", i); goto fail; } pkt_filter = (struct brcmf_pkt_filter_le *)buf; /* Parse packet filter id. */ pkt_filter->id = 0; if (!kstrtoul(argv[0], 0, &res)) pkt_filter->id = cpu_to_le32((u32)res); /* Parse filter polarity. */ pkt_filter->negate_match = 0; if (!kstrtoul(argv[1], 0, &res)) pkt_filter->negate_match = cpu_to_le32((u32)res); /* Parse filter type. */ pkt_filter->type = 0; if (!kstrtoul(argv[2], 0, &res)) pkt_filter->type = cpu_to_le32((u32)res); /* Parse pattern filter offset. */ pkt_filter->u.pattern.offset = 0; if (!kstrtoul(argv[3], 0, &res)) pkt_filter->u.pattern.offset = cpu_to_le32((u32)res); /* Parse pattern filter mask. */ mask_size = brcmf_c_pattern_atoh(argv[4], (char *)pkt_filter->u.pattern.mask_and_pattern); /* Parse pattern filter pattern. */ pattern_size = brcmf_c_pattern_atoh(argv[5], (char *)&pkt_filter->u.pattern.mask_and_pattern[mask_size]); if (mask_size != pattern_size) { brcmf_err("Mask and pattern not the same size\n"); goto fail; } pkt_filter->u.pattern.size_bytes = cpu_to_le32(mask_size); buf_len = offsetof(struct brcmf_pkt_filter_le, u.pattern.mask_and_pattern); buf_len += mask_size + pattern_size; err = brcmf_fil_iovar_data_set(ifp, "pkt_filter_add", pkt_filter, buf_len); if (err) brcmf_err("Set pkt_filter_add error (%d)\n", err); fail: kfree(arg_org); kfree(buf); }
void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg) { const char *str; struct brcmf_pkt_filter pkt_filter; struct brcmf_pkt_filter *pkt_filterp; int buf_len; int str_len; int rc; u32 mask_size; u32 pattern_size; char *argv[8], *buf = 0; int i = 0; char *arg_save = 0, *arg_org = 0; arg_save = kmalloc(strlen(arg) + 1, GFP_ATOMIC); if (!arg_save) { BRCMF_ERROR(("%s: kmalloc failed\n", __func__)); goto fail; } arg_org = arg_save; buf = kmalloc(PKTFILTER_BUF_SIZE, GFP_ATOMIC); if (!buf) { BRCMF_ERROR(("%s: kmalloc failed\n", __func__)); goto fail; } strcpy(arg_save, arg); argv[i] = strsep(&arg_save, " "); while (argv[i++]) argv[i] = strsep(&arg_save, " "); i = 0; if (NULL == argv[i]) { BRCMF_ERROR(("No args provided\n")); goto fail; } str = "pkt_filter_add"; strcpy(buf, str); str_len = strlen(str); buf_len = str_len + 1; pkt_filterp = (struct brcmf_pkt_filter *) (buf + str_len + 1); /* Parse packet filter id. */ pkt_filter.id = simple_strtoul(argv[i], NULL, 0); if (NULL == argv[++i]) { BRCMF_ERROR(("Polarity not provided\n")); goto fail; } /* Parse filter polarity. */ pkt_filter.negate_match = simple_strtoul(argv[i], NULL, 0); if (NULL == argv[++i]) { BRCMF_ERROR(("Filter type not provided\n")); goto fail; } /* Parse filter type. */ pkt_filter.type = simple_strtoul(argv[i], NULL, 0); if (NULL == argv[++i]) { BRCMF_ERROR(("Offset not provided\n")); goto fail; } /* Parse pattern filter offset. */ pkt_filter.u.pattern.offset = simple_strtoul(argv[i], NULL, 0); if (NULL == argv[++i]) { BRCMF_ERROR(("Bitmask not provided\n")); goto fail; } /* Parse pattern filter mask. */ mask_size = brcmf_c_pattern_atoh (argv[i], (char *)pkt_filterp->u.pattern.mask_and_pattern); if (NULL == argv[++i]) { BRCMF_ERROR(("Pattern not provided\n")); goto fail; } /* Parse pattern filter pattern. */ pattern_size = brcmf_c_pattern_atoh(argv[i], (char *)&pkt_filterp->u.pattern. mask_and_pattern[mask_size]); if (mask_size != pattern_size) { BRCMF_ERROR(("Mask and pattern not the same size\n")); goto fail; } pkt_filter.u.pattern.size_bytes = mask_size; buf_len += BRCMF_PKT_FILTER_FIXED_LEN; buf_len += (BRCMF_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size); /* Keep-alive attributes are set in local * variable (keep_alive_pkt), and ** then memcpy'ed into buffer (keep_alive_pktp) since there is no ** guarantee that the buffer is properly aligned. */ memcpy((char *)pkt_filterp, &pkt_filter, BRCMF_PKT_FILTER_FIXED_LEN + BRCMF_PKT_FILTER_PATTERN_FIXED_LEN); rc = brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_VAR, buf, buf_len); rc = rc >= 0 ? 0 : rc; if (rc) BRCMF_TRACE(("%s: failed to add pktfilter %s, retcode = %d\n", __func__, arg, rc)); else BRCMF_TRACE(("%s: successfully added pktfilter %s\n", __func__, arg)); fail: kfree(arg_org); kfree(buf); }
void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg) { const char *str; struct brcmf_pkt_filter_le pkt_filter; struct brcmf_pkt_filter_le *pkt_filterp; unsigned long res; int buf_len; int str_len; int rc; u32 mask_size; u32 pattern_size; char *argv[8], *buf = NULL; int i = 0; char *arg_save = NULL, *arg_org = NULL; arg_save = kstrdup(arg, GFP_ATOMIC); if (!arg_save) goto fail; arg_org = arg_save; buf = kmalloc(PKTFILTER_BUF_SIZE, GFP_ATOMIC); if (!buf) goto fail; argv[i] = strsep(&arg_save, " "); while (argv[i++]) argv[i] = strsep(&arg_save, " "); i = 0; if (NULL == argv[i]) { brcmf_dbg(ERROR, "No args provided\n"); goto fail; } str = "pkt_filter_add"; strcpy(buf, str); str_len = strlen(str); buf_len = str_len + 1; pkt_filterp = (struct brcmf_pkt_filter_le *) (buf + str_len + 1); /* Parse packet filter id. */ pkt_filter.id = 0; if (!kstrtoul(argv[i], 0, &res)) pkt_filter.id = cpu_to_le32((u32)res); if (NULL == argv[++i]) { brcmf_dbg(ERROR, "Polarity not provided\n"); goto fail; } /* Parse filter polarity. */ pkt_filter.negate_match = 0; if (!kstrtoul(argv[i], 0, &res)) pkt_filter.negate_match = cpu_to_le32((u32)res); if (NULL == argv[++i]) { brcmf_dbg(ERROR, "Filter type not provided\n"); goto fail; } /* Parse filter type. */ pkt_filter.type = 0; if (!kstrtoul(argv[i], 0, &res)) pkt_filter.type = cpu_to_le32((u32)res); if (NULL == argv[++i]) { brcmf_dbg(ERROR, "Offset not provided\n"); goto fail; } /* Parse pattern filter offset. */ pkt_filter.u.pattern.offset = 0; if (!kstrtoul(argv[i], 0, &res)) pkt_filter.u.pattern.offset = cpu_to_le32((u32)res); if (NULL == argv[++i]) { brcmf_dbg(ERROR, "Bitmask not provided\n"); goto fail; } /* Parse pattern filter mask. */ mask_size = brcmf_c_pattern_atoh (argv[i], (char *)pkt_filterp->u.pattern.mask_and_pattern); if (NULL == argv[++i]) { brcmf_dbg(ERROR, "Pattern not provided\n"); goto fail; } /* Parse pattern filter pattern. */ pattern_size = brcmf_c_pattern_atoh(argv[i], (char *)&pkt_filterp->u.pattern. mask_and_pattern[mask_size]); if (mask_size != pattern_size) { brcmf_dbg(ERROR, "Mask and pattern not the same size\n"); goto fail; } pkt_filter.u.pattern.size_bytes = cpu_to_le32(mask_size); buf_len += BRCMF_PKT_FILTER_FIXED_LEN; buf_len += (BRCMF_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size); /* Keep-alive attributes are set in local * variable (keep_alive_pkt), and ** then memcpy'ed into buffer (keep_alive_pktp) since there is no ** guarantee that the buffer is properly aligned. */ memcpy((char *)pkt_filterp, &pkt_filter, BRCMF_PKT_FILTER_FIXED_LEN + BRCMF_PKT_FILTER_PATTERN_FIXED_LEN); rc = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, buf, buf_len); rc = rc >= 0 ? 0 : rc; if (rc) brcmf_dbg(TRACE, "failed to add pktfilter %s, retcode = %d\n", arg, rc); else brcmf_dbg(TRACE, "successfully added pktfilter %s\n", arg); fail: kfree(arg_org); kfree(buf); }