static s32 brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set) { struct brcmf_pub *drvr = ifp->drvr; s32 err; if (drvr->bus_if->state != BRCMF_BUS_DATA) { brcmf_err("bus is down. we have nothing to do.\n"); return -EIO; } if (data != NULL) len = min_t(uint, len, BRCMF_DCMD_MAXLEN); if (set) err = brcmf_proto_cdc_set_dcmd(drvr, ifp->idx, cmd, data, len); else err = brcmf_proto_cdc_query_dcmd(drvr, ifp->idx, cmd, data, len); if (err >= 0) err = 0; else brcmf_err("Failed err=%d\n", err); return err; }
static void brcmf_c_arp_offload_set(struct brcmf_pub *drvr, int arp_mode) { char iovbuf[32]; int retcode; brcmf_c_mkiovar("arp_ol", (char *)&arp_mode, 4, iovbuf, sizeof(iovbuf)); retcode = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf)); retcode = retcode >= 0 ? 0 : retcode; if (retcode) brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, retcode = %d\n", arp_mode, retcode); else brcmf_dbg(TRACE, "successfully set ARP offload mode to 0x%x\n", arp_mode); }
static void brcmf_c_arp_offload_enable(struct brcmf_pub *drvr, int arp_enable) { char iovbuf[32]; int retcode; __le32 arp_enable_le; arp_enable_le = cpu_to_le32(arp_enable); brcmf_c_mkiovar("arpoe", (char *)&arp_enable_le, 4, iovbuf, sizeof(iovbuf)); retcode = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf)); retcode = retcode >= 0 ? 0 : retcode; if (retcode) brcmf_dbg(TRACE, "failed to enable ARP offload to %d, retcode = %d\n", arp_enable, retcode); else brcmf_dbg(TRACE, "successfully enabled ARP offload to %d\n", arp_enable); }
int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr) { char iovbuf[BRCMF_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" + '\0' + bitvec */ uint up = 0; char buf[128], *ptr; u32 dongle_align = drvr->bus_if->align; u32 glom = 0; u32 roaming = 1; uint bcn_timeout = 3; int scan_assoc_time = 40; int scan_unassoc_time = 40; int i; mutex_lock(&drvr->proto_block); /* Set Country code */ if (drvr->country_code[0] != 0) { if (brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_COUNTRY, drvr->country_code, sizeof(drvr->country_code)) < 0) brcmf_dbg(ERROR, "country code setting failed\n"); } /* query for 'ver' to get version info from firmware */ memset(buf, 0, sizeof(buf)); ptr = buf; brcmf_c_mkiovar("ver", NULL, 0, buf, sizeof(buf)); brcmf_proto_cdc_query_dcmd(drvr, 0, BRCMF_C_GET_VAR, buf, sizeof(buf)); strsep(&ptr, "\n"); /* Print fw version info */ brcmf_dbg(ERROR, "Firmware version = %s\n", buf); /* Match Host and Dongle rx alignment */ brcmf_c_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf, sizeof(iovbuf)); brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf)); /* disable glom option per default */ brcmf_c_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf)); brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf)); /* Setup timeout if Beacons are lost and roam is off to report link down */ brcmf_c_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf, sizeof(iovbuf)); brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf)); /* Enable/Disable build-in roaming to allowed ext supplicant to take of romaing */ brcmf_c_mkiovar("roam_off", (char *)&roaming, 4, iovbuf, sizeof(iovbuf)); brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf)); /* Force STA UP */ brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_UP, (char *)&up, sizeof(up)); /* Setup event_msgs */ brcmf_c_mkiovar("event_msgs", drvr->eventmask, BRCMF_EVENTING_MASK_LEN, iovbuf, sizeof(iovbuf)); brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf)); brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_SCAN_CHANNEL_TIME, (char *)&scan_assoc_time, sizeof(scan_assoc_time)); brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_SCAN_UNASSOC_TIME, (char *)&scan_unassoc_time, sizeof(scan_unassoc_time)); /* Set and enable ARP offload feature */ brcmf_c_arp_offload_set(drvr, BRCMF_ARPOL_MODE); brcmf_c_arp_offload_enable(drvr, true); /* Set up pkt filter */ for (i = 0; i < drvr->pktfilter_count; i++) { brcmf_c_pktfilter_offload_set(drvr, drvr->pktfilter[i]); brcmf_c_pktfilter_offload_enable(drvr, drvr->pktfilter[i], 0, true); } mutex_unlock(&drvr->proto_block); return 0; }
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); }
void brcmf_c_pktfilter_offload_enable(struct brcmf_pub *drvr, char *arg, int enable, int master_mode) { unsigned long res; char *argv[8]; int i = 0; const char *str; int buf_len; int str_len; char *arg_save = NULL, *arg_org = NULL; int rc; char buf[128]; struct brcmf_pkt_filter_enable_le enable_parm; struct brcmf_pkt_filter_enable_le *pkt_filterp; __le32 mmode_le; arg_save = kmalloc(strlen(arg) + 1, GFP_ATOMIC); if (!arg_save) goto fail; arg_org = arg_save; memcpy(arg_save, arg, strlen(arg) + 1); argv[i] = strsep(&arg_save, " "); i = 0; if (NULL == argv[i]) { brcmf_dbg(ERROR, "No args provided\n"); goto fail; } str = "pkt_filter_enable"; str_len = strlen(str); strncpy(buf, str, str_len); buf[str_len] = '\0'; buf_len = str_len + 1; pkt_filterp = (struct brcmf_pkt_filter_enable_le *) (buf + str_len + 1); /* Parse packet filter id. */ enable_parm.id = 0; if (!kstrtoul(argv[i], 0, &res)) enable_parm.id = cpu_to_le32((u32)res); /* Parse enable/disable value. */ enable_parm.enable = cpu_to_le32(enable); buf_len += sizeof(enable_parm); memcpy((char *)pkt_filterp, &enable_parm, sizeof(enable_parm)); /* Enable/disable the specified filter. */ 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); /* Contorl the master mode */ mmode_le = cpu_to_le32(master_mode); brcmf_c_mkiovar("pkt_filter_mode", (char *)&mmode_le, 4, buf, sizeof(buf)); rc = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, buf, sizeof(buf)); rc = rc >= 0 ? 0 : rc; if (rc) brcmf_dbg(TRACE, "failed to add pktfilter %s, retcode = %d\n", arg, rc); fail: kfree(arg_org); }
int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr) { char iovbuf[BRCMF_EVENTING_MASK_LEN + 12]; uint up = 0; char buf[128], *ptr; u32 dongle_align = drvr->bus_if->align; u32 glom = 0; __le32 roaming_le = cpu_to_le32(1); __le32 bcn_timeout_le = cpu_to_le32(3); __le32 scan_assoc_time_le = cpu_to_le32(40); __le32 scan_unassoc_time_le = cpu_to_le32(40); int i; mutex_lock(&drvr->proto_block); if (drvr->country_code[0] != 0) { if (brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_COUNTRY, drvr->country_code, sizeof(drvr->country_code)) < 0) brcmf_dbg(ERROR, "country code setting failed\n"); } memset(buf, 0, sizeof(buf)); ptr = buf; brcmf_c_mkiovar("ver", NULL, 0, buf, sizeof(buf)); brcmf_proto_cdc_query_dcmd(drvr, 0, BRCMF_C_GET_VAR, buf, sizeof(buf)); strsep(&ptr, "\n"); brcmf_dbg(ERROR, "Firmware version = %s\n", buf); brcmf_c_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf, sizeof(iovbuf)); brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf)); brcmf_c_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf)); brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf)); brcmf_c_mkiovar("bcn_timeout", (char *)&bcn_timeout_le, 4, iovbuf, sizeof(iovbuf)); brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf)); /* Enable/Disable build-in roaming to allowed ext supplicant to take of romaing */ brcmf_c_mkiovar("roam_off", (char *)&roaming_le, 4, iovbuf, sizeof(iovbuf)); brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf)); brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_UP, (char *)&up, sizeof(up)); brcmf_c_mkiovar("event_msgs", drvr->eventmask, BRCMF_EVENTING_MASK_LEN, iovbuf, sizeof(iovbuf)); brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf)); brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_SCAN_CHANNEL_TIME, (char *)&scan_assoc_time_le, sizeof(scan_assoc_time_le)); brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_SCAN_UNASSOC_TIME, (char *)&scan_unassoc_time_le, sizeof(scan_unassoc_time_le)); brcmf_c_arp_offload_set(drvr, BRCMF_ARPOL_MODE); brcmf_c_arp_offload_enable(drvr, true); for (i = 0; i < drvr->pktfilter_count; i++) { brcmf_c_pktfilter_offload_set(drvr, drvr->pktfilter[i]); brcmf_c_pktfilter_offload_enable(drvr, drvr->pktfilter[i], 0, true); } mutex_unlock(&drvr->proto_block); return 0; }