Message ID | BLU436-SMTP2184EC6C2C7640F423277BDB9A0@phx.gbl |
---|---|
State | Changes Requested |
Headers | show |
Hi, On Thu, Mar 31, 2016 at 6:48 PM, Adrian Panella <ianchi74@outlook.com> wrote: > > > From df9a676bb3ba225f0fd6621dbaeec945baf3153d Mon Sep 17 00:00:00 2001 > From: Adrian Panella <ianchi74@outlook.com> > Date: Wed, 30 Mar 2016 23:31:06 -0600 > Subject: [PATCH 12/15] caldata-utils: new package to manipulate ath10k > calibration data > > Signed-off-by: Adrian Panella <ianchi74@outlook.com> > --- > package/utils/caldata-utils/Makefile | 60 +++++++++ > package/utils/caldata-utils/src/Makefile | 8 ++ > package/utils/caldata-utils/src/caldata.c | 213 ++++++++++++++++++++++++++++++ > package/utils/caldata-utils/src/caldata.h | 42 ++++++ > package/utils/caldata-utils/src/utils.c | 72 ++++++++++ > 5 files changed, 395 insertions(+) > create mode 100644 package/utils/caldata-utils/Makefile > create mode 100644 package/utils/caldata-utils/src/Makefile > create mode 100644 package/utils/caldata-utils/src/caldata.c > create mode 100644 package/utils/caldata-utils/src/caldata.h > create mode 100644 package/utils/caldata-utils/src/utils.c > > diff --git a/package/utils/caldata-utils/Makefile b/package/utils/caldata-utils/Makefile > new file mode 100644 > index 0000000..eff7761 > --- /dev/null > +++ b/package/utils/caldata-utils/Makefile > @@ -0,0 +1,60 @@ > +# > +# Copyright (C) 2006-2010 OpenWrt.org > +# Copyright (C) 2016 Adrian Panella > +# > +# This is free software, licensed under the GNU General Public License v2. > +# See /LICENSE for more information. > +# > + > +include $(TOPDIR)/rules.mk > + > +PKG_NAME:=caldata-utils > +PKG_RELEASE:=1 > + > +PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) > +PKG_BUILD_DEPENDS:=USE_UCLIBC:argp-standalone USE_MUSL:argp-standalone > + > +include $(INCLUDE_DIR)/package.mk > + > +ifdef CONFIG_USE_UCLIBC > + LIBARGP="-largp" > +endif > + > +ifdef CONFIG_USE_MUSL > + LIBARGP="-largp" > +endif > + > + > +define Package/caldata-utils > + SECTION:=utils > + CATEGORY:=Utilities > + TITLE:=Utility to manipulate calibration data for ath10k > + MAINTAINER:=Adrian Panella <ianchi74@outlook.com> > +endef > + > +define Package/caldata-utils/description > + This package contains an utility to manipulate calibration data for ath10k drivers. > + It enables to extract from MTD partition or file and to patch MAC address fixing the checksum. > +endef > + > +define Build/Prepare > + mkdir -p $(PKG_BUILD_DIR) > + $(CP) ./src/* $(PKG_BUILD_DIR)/ > +endef > + > +define Build/Configure > +endef > + > +define Build/Compile > + $(MAKE) -C $(PKG_BUILD_DIR) \ > + CC="$(TARGET_CC)" \ > + CFLAGS="$(TARGET_CFLAGS) -Wall" \ > + LDFLAGS="$(TARGET_LDFLAGS) $(LIBARGP)" > +endef > + > +define Package/caldata-utils/install > + $(INSTALL_DIR) $(1)/usr/sbin > + $(INSTALL_BIN) $(PKG_BUILD_DIR)/caldata $(1)/usr/sbin/ > +endef > + > +$(eval $(call BuildPackage,caldata-utils)) > diff --git a/package/utils/caldata-utils/src/Makefile b/package/utils/caldata-utils/src/Makefile > new file mode 100644 > index 0000000..57ab936 > --- /dev/null > +++ b/package/utils/caldata-utils/src/Makefile > @@ -0,0 +1,8 @@ > + > +all: caldata > + > +caldata: caldata.c utils.c > + $(CC) $(CFLAGS) -o $@ caldata.c utils.c $(LDFLAGS) > + > +clean: > + rm caldata > diff --git a/package/utils/caldata-utils/src/caldata.c b/package/utils/caldata-utils/src/caldata.c > new file mode 100644 > index 0000000..d5391d5 > --- /dev/null > +++ b/package/utils/caldata-utils/src/caldata.c > @@ -0,0 +1,213 @@ > +/* > + * > + * Copyright (C) 2016 Adrian Panella <ianchi74@outlook.com> > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License > + * as published by the Free Software Foundation; either version 2 > + * of the License, or (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. > + */ > + > +/* > + * > + * caldata > + * > + * Utility to manipulate calibration data for ath10k drivers. > + * It enables to extract from MTD partition or file and to patch MAC address fixing the checksum. > + * > + */ > + > + > +#include <stdio.h> > +#include <argp.h> > +#include <stdlib.h> > + > +#include "caldata.h" > + > + > +/* Parse a single option. */ > +static error_t parse_opt (int key, char *arg, struct argp_state *state) > +{ > + struct arguments *arguments = state->input; > + > + switch (key) > + { > + case 'i': > + arguments->input_file = arg; > + break; > + > + case 'f': > + arguments->output_file = arg; > + break; > + > + case 'o': > + sscanf(arg,"%li", &arguments->offset); > + break; > + > + case 's': > + sscanf(arg,"%li", &arguments->size); > + break; > + > + case 'a': > + > + if(!isMAC(arg)) > + argp_error(state,"address is not a valid MAC address"); > + > + arguments->macaddr = arg; > + break; > + > + case 'v': > + arguments->verify = 1; > + break; > + > + case ARGP_KEY_END: //all options processed, verify consistency > + > + if(!arguments->input_file) > + argp_error(state,"No input file or partition specified."); > + > + if(!arguments->verify && !arguments->output_file) > + argp_error(state, "Must specify either -f FILE or -v."); > + > + break; > + > + default: > + return ARGP_ERR_UNKNOWN; > + } > + return 0; > +} > + > + > +int loadfile(char *file, void **data, int offset, int size) { > + *data=NULL; > + char *source = NULL; > + > + > + char mtdpath[32]; > + FILE *fp=NULL; > + > + //try input as partition > + int mtdnr = getMTD(file); > + if(mtdnr>=0) { > + sprintf(mtdpath, "/dev/mtdblock%d", mtdnr); > + fp = fopen(mtdpath, "rb"); > + } > + //try as file > + if(!fp) > + fp = fopen(file, "rb"); > + > + if (fp != NULL) { > + /* Go to the end of the file. */ > + if (fseek(fp, 0L, SEEK_END) == 0) { > + /* Get the size of the file. */ > + long filesize = ftell(fp); > + if (filesize == -1) { > + fclose(fp); > + return -1; } > + > + size= size ? size : (filesize - offset); > + if(size + offset > filesize) { > + fputs("Offset + size gets past EOF", stderr); > + fclose(fp); > + exit(1);} > + > + source = malloc(size + 1); > + > + /* offset from the start of the file. */ > + if (fseek(fp, offset, SEEK_SET) != 0) { > + free(source); > + fclose(fp); > + return -1;} > + > + /* Read file into memory. */ > + size_t newLen = fread(source, sizeof(char), size, fp); > + if (newLen == 0) { > + free(source); > + fclose(fp); > + return -1; > + } > + else { > + fclose(fp); > + *data=source; > + return size; > + } > + } > + } > + return -1; > +} > + > +int main (int argc, char **argv) > +{ > + struct arguments arguments; > + unsigned short ret=0; > + > + /* Default values. */ > + arguments.input_file = NULL; > + arguments.output_file = NULL; > + arguments.offset = 0; > + arguments.size = 0; > + arguments.macaddr = NULL; > + arguments.verify = 0; > + > + /* Parse arguments and validate*/ > + argp_parse (&argp, argc, argv, 0, 0, &arguments); > + > + > + // read input data > + unsigned short *data; > + int data_len=loadfile(arguments.input_file,(void **)&data, arguments.offset, arguments.size); > + > + if(data_len<0) { > + fputs("Error reading input file/partition.\n", stderr); > + exit(1); > + } > + > + unsigned char *mac=(unsigned char *)data+6; > + > + if(arguments.verify) { > + > + printf("Size: %d\n", data[0]); > + printf("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); > + ret=checksum(data, data[0]) ? 1 : 0; > + printf("Checksum: 0x%04x (%s)\n", data[1], ret ? "ERROR" : "OK"); > + if(ret) > + fputs("Calibration data checksum error\n", stderr); > + > + free(data); > + exit(ret); > + } > + > + if(arguments.macaddr) { > + sscanf(arguments.macaddr,"%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]); > + data[1]=0; > + data[1]=checksum(data, data[0]); > + } > + > + FILE *fp=fopen(arguments.output_file,"wb"); > + > + if(!fp) { > + fputs("Error opening output file\n", stderr); > + free(data); > + exit(1); > + } > + > + if(fwrite(data, data_len, 1, fp)!=1) { > + fputs("Error writing output file\n", stderr); > + free(data); > + fclose(fp); > + exit(1); > + } > + > + > + fclose(fp); > + free(data); > + exit(0); > +} > diff --git a/package/utils/caldata-utils/src/caldata.h b/package/utils/caldata-utils/src/caldata.h > new file mode 100644 > index 0000000..27c8175 > --- /dev/null > +++ b/package/utils/caldata-utils/src/caldata.h > @@ -0,0 +1,42 @@ > + > +/* Documentation */ > +const char *argp_program_version = "caldata utils 1.0"; > +static char doc[] = "caldata - Utility to manipulate calibration data for ath10k"; > +static char args_doc[] = "ARG1 ARG2"; > + > +/* Options */ > +static struct argp_option options[] = { > + {"input", 'i', "PARTITION/FILE", 0, "Read from PARTITION or FILE" }, > + {"output", 'f', "FILE", 0, "Output to FILE." }, > + {"offset", 'o', "BYTES", 0, "Skip first BYTES" }, > + {"size", 's', "BYTES", 0, "Size of data to read"}, > + {"maddress", 'a', "ADDRESS", 0, "new MAC address to assign"}, > + {"verify", 'v', 0, 0, "Only verify input, no output"}, > + { 0 } > +}; > + > +/* Used by main to communicate with parse_opt. */ > +struct arguments > +{ > + char *input_file; > + char *output_file; > + > + long int offset; > + long int size; > + char *macaddr; > + int newmac[6]; > + > + int verify; > +}; > + > +static error_t parse_opt (int key, char *arg, struct argp_state *state); > + > +static struct argp argp = { options, parse_opt, args_doc, doc }; > + > + > +// Utils > + > +int isMAC(char *s); > +int getMTD(char *name); > +unsigned short checksum(void *caldata, int size); > + > diff --git a/package/utils/caldata-utils/src/utils.c b/package/utils/caldata-utils/src/utils.c > new file mode 100644 > index 0000000..d8bda63 > --- /dev/null > +++ b/package/utils/caldata-utils/src/utils.c > @@ -0,0 +1,72 @@ > +/* > + * > + * Copyright (C) 2016 Adrian Panella <ianchi74@outlook.com> > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License > + * as published by the Free Software Foundation; either version 2 > + * of the License, or (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. > + */ > + > +#include <stdio.h> > +#include <stdlib.h> > +#include <ctype.h> > +#include <string.h> > + > +int isMAC(char *s) { > + int i; > + for(i = 0; i < 17; i++) { > + if(i % 3 != 2 && !isxdigit(s[i])) > + return 0; > + if(i % 3 == 2 && s[i] != ':') > + return 0; > + } > + if(s[17] != '\0') > + return 0; > + return 1; > +} > + > + > +int getMTD(char *name) > +{ > + int device = -1; > + int dev; > + char part[32]; > + FILE *fp = fopen("/proc/mtd", "rb"); > + if (!fp) > + return -1; > + while (!feof(fp) && fscanf(fp, "%*[^0-9]%d: %*s %*s \"%[^\"]\"", &dev, part) == 2) { > + if (!strcmp(part, name)) { > + device = dev; > + break; > + } > + } > + fclose(fp); > + return device; > +} > + > + > +unsigned short checksum(void *caldata, int size) > +{ > + unsigned short *ptr = (unsigned short *)caldata; > + unsigned short crc = 0; > + int i; > + > + for (i = 0; i < size; i += 2) { > + crc ^= *ptr; > + ptr++; > + } > + crc = ~crc; > + return crc; > +} > + > + > -- > 1.9.1 > _______________________________________________ > openwrt-devel mailing list > openwrt-devel@lists.openwrt.org > https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel I'm not convinced this should go into the core packages, but instead to https://github.com/openwrt/packages. - Pushpal
So far I find it essential to make ath10k work on EA8500 with the right mac address (and perhaps on other routers using QCA99x0), and so a prerequisite for that profile. That was why I proposed it in the core packages. More or less like the uboot-env utilities, which are also a prerequisite for this profile. Or perhaps like the "oseama" or "rbcfg" packages in other platforms. Most of the functionality could be covered easily with a script and was my first attempt, but I couldn't find a way to code in a sh script the checksum calculation function to be able to patch the calibration data; and so ended writing it as a C helper utility. Basically the essential part is the small checksum function in utils.c. If you help me with some ideas, I can try to refactor it into a script. -----Original Message----- From: Pushpal Sidhu [mailto:psidhu@gateworks.com] Sent: viernes, 01 de abril de 2016 12:57 p.m. To: Adrian Panella Cc: OpenWrt Development List; John Crispin Subject: Re: [OpenWrt-Devel] [PATCH 4/8] caldata-utils: new package to manipulate ath10k Hi, On Thu, Mar 31, 2016 at 6:48 PM, Adrian Panella <ianchi74@outlook.com> wrote: > > > From df9a676bb3ba225f0fd6621dbaeec945baf3153d Mon Sep 17 00:00:00 2001 > From: Adrian Panella <ianchi74@outlook.com> > Date: Wed, 30 Mar 2016 23:31:06 -0600 > Subject: [PATCH 12/15] caldata-utils: new package to manipulate ath10k > calibration data > > Signed-off-by: Adrian Panella <ianchi74@outlook.com> > --- > package/utils/caldata-utils/Makefile | 60 +++++++++ > package/utils/caldata-utils/src/Makefile | 8 ++ > package/utils/caldata-utils/src/caldata.c | 213 > ++++++++++++++++++++++++++++++ package/utils/caldata-utils/src/caldata.h | 42 ++++++ > package/utils/caldata-utils/src/utils.c | 72 ++++++++++ > 5 files changed, 395 insertions(+) > create mode 100644 package/utils/caldata-utils/Makefile > create mode 100644 package/utils/caldata-utils/src/Makefile > create mode 100644 package/utils/caldata-utils/src/caldata.c > create mode 100644 package/utils/caldata-utils/src/caldata.h > create mode 100644 package/utils/caldata-utils/src/utils.c > > diff --git a/package/utils/caldata-utils/Makefile > b/package/utils/caldata-utils/Makefile > new file mode 100644 > index 0000000..eff7761 > --- /dev/null > +++ b/package/utils/caldata-utils/Makefile > @@ -0,0 +1,60 @@ > +# > +# Copyright (C) 2006-2010 OpenWrt.org # Copyright (C) 2016 Adrian > +Panella # # This is free software, licensed under the GNU General > +Public License v2. > +# See /LICENSE for more information. > +# > + > +include $(TOPDIR)/rules.mk > + > +PKG_NAME:=caldata-utils > +PKG_RELEASE:=1 > + > +PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) > +PKG_BUILD_DEPENDS:=USE_UCLIBC:argp-standalone > +USE_MUSL:argp-standalone > + > +include $(INCLUDE_DIR)/package.mk > + > +ifdef CONFIG_USE_UCLIBC > + LIBARGP="-largp" > +endif > + > +ifdef CONFIG_USE_MUSL > + LIBARGP="-largp" > +endif > + > + > +define Package/caldata-utils > + SECTION:=utils > + CATEGORY:=Utilities > + TITLE:=Utility to manipulate calibration data for ath10k > + MAINTAINER:=Adrian Panella <ianchi74@outlook.com> endef > + > +define Package/caldata-utils/description This package contains an > +utility to manipulate calibration data for ath10k drivers. > + It enables to extract from MTD partition or file and to patch MAC address fixing the checksum. > +endef > + > +define Build/Prepare > + mkdir -p $(PKG_BUILD_DIR) > + $(CP) ./src/* $(PKG_BUILD_DIR)/ > +endef > + > +define Build/Configure > +endef > + > +define Build/Compile > + $(MAKE) -C $(PKG_BUILD_DIR) \ > + CC="$(TARGET_CC)" \ > + CFLAGS="$(TARGET_CFLAGS) -Wall" \ > + LDFLAGS="$(TARGET_LDFLAGS) $(LIBARGP)" > +endef > + > +define Package/caldata-utils/install > + $(INSTALL_DIR) $(1)/usr/sbin > + $(INSTALL_BIN) $(PKG_BUILD_DIR)/caldata $(1)/usr/sbin/ endef > + > +$(eval $(call BuildPackage,caldata-utils)) > diff --git a/package/utils/caldata-utils/src/Makefile > b/package/utils/caldata-utils/src/Makefile > new file mode 100644 > index 0000000..57ab936 > --- /dev/null > +++ b/package/utils/caldata-utils/src/Makefile > @@ -0,0 +1,8 @@ > + > +all: caldata > + > +caldata: caldata.c utils.c > + $(CC) $(CFLAGS) -o $@ caldata.c utils.c $(LDFLAGS) > + > +clean: > + rm caldata > diff --git a/package/utils/caldata-utils/src/caldata.c > b/package/utils/caldata-utils/src/caldata.c > new file mode 100644 > index 0000000..d5391d5 > --- /dev/null > +++ b/package/utils/caldata-utils/src/caldata.c > @@ -0,0 +1,213 @@ > +/* > + * > + * Copyright (C) 2016 Adrian Panella <ianchi74@outlook.com> > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License > + * as published by the Free Software Foundation; either version 2 > + * of the License, or (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. > + */ > + > +/* > + * > + * caldata > + * > + * Utility to manipulate calibration data for ath10k drivers. > + * It enables to extract from MTD partition or file and to patch MAC address fixing the checksum. > + * > + */ > + > + > +#include <stdio.h> > +#include <argp.h> > +#include <stdlib.h> > + > +#include "caldata.h" > + > + > +/* Parse a single option. */ > +static error_t parse_opt (int key, char *arg, struct argp_state > +*state) { > + struct arguments *arguments = state->input; > + > + switch (key) > + { > + case 'i': > + arguments->input_file = arg; > + break; > + > + case 'f': > + arguments->output_file = arg; > + break; > + > + case 'o': > + sscanf(arg,"%li", &arguments->offset); > + break; > + > + case 's': > + sscanf(arg,"%li", &arguments->size); > + break; > + > + case 'a': > + > + if(!isMAC(arg)) > + argp_error(state,"address is not a valid MAC address"); > + > + arguments->macaddr = arg; > + break; > + > + case 'v': > + arguments->verify = 1; > + break; > + > + case ARGP_KEY_END: //all options processed, verify consistency > + > + if(!arguments->input_file) > + argp_error(state,"No input file or partition > + specified."); > + > + if(!arguments->verify && !arguments->output_file) > + argp_error(state, "Must specify either -f FILE or -v."); > + > + break; > + > + default: > + return ARGP_ERR_UNKNOWN; > + } > + return 0; > +} > + > + > +int loadfile(char *file, void **data, int offset, int size) { > + *data=NULL; > + char *source = NULL; > + > + > + char mtdpath[32]; > + FILE *fp=NULL; > + > + //try input as partition > + int mtdnr = getMTD(file); > + if(mtdnr>=0) { > + sprintf(mtdpath, "/dev/mtdblock%d", mtdnr); > + fp = fopen(mtdpath, "rb"); > + } > + //try as file > + if(!fp) > + fp = fopen(file, "rb"); > + > + if (fp != NULL) { > + /* Go to the end of the file. */ > + if (fseek(fp, 0L, SEEK_END) == 0) { > + /* Get the size of the file. */ > + long filesize = ftell(fp); > + if (filesize == -1) { > + fclose(fp); > + return -1; } > + > + size= size ? size : (filesize - offset); > + if(size + offset > filesize) { > + fputs("Offset + size gets past EOF", stderr); > + fclose(fp); > + exit(1);} > + > + source = malloc(size + 1); > + > + /* offset from the start of the file. */ > + if (fseek(fp, offset, SEEK_SET) != 0) { > + free(source); > + fclose(fp); > + return -1;} > + > + /* Read file into memory. */ > + size_t newLen = fread(source, sizeof(char), size, fp); > + if (newLen == 0) { > + free(source); > + fclose(fp); > + return -1; > + } > + else { > + fclose(fp); > + *data=source; > + return size; > + } > + } > + } > + return -1; > +} > + > +int main (int argc, char **argv) > +{ > + struct arguments arguments; > + unsigned short ret=0; > + > + /* Default values. */ > + arguments.input_file = NULL; > + arguments.output_file = NULL; > + arguments.offset = 0; > + arguments.size = 0; > + arguments.macaddr = NULL; > + arguments.verify = 0; > + > + /* Parse arguments and validate*/ > + argp_parse (&argp, argc, argv, 0, 0, &arguments); > + > + > + // read input data > + unsigned short *data; > + int data_len=loadfile(arguments.input_file,(void **)&data, > + arguments.offset, arguments.size); > + > + if(data_len<0) { > + fputs("Error reading input file/partition.\n", stderr); > + exit(1); > + } > + > + unsigned char *mac=(unsigned char *)data+6; > + > + if(arguments.verify) { > + > + printf("Size: %d\n", data[0]); > + printf("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); > + ret=checksum(data, data[0]) ? 1 : 0; > + printf("Checksum: 0x%04x (%s)\n", data[1], ret ? "ERROR" : "OK"); > + if(ret) > + fputs("Calibration data checksum error\n", stderr); > + > + free(data); > + exit(ret); > + } > + > + if(arguments.macaddr) { > + sscanf(arguments.macaddr,"%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]); > + data[1]=0; > + data[1]=checksum(data, data[0]); > + } > + > + FILE *fp=fopen(arguments.output_file,"wb"); > + > + if(!fp) { > + fputs("Error opening output file\n", stderr); > + free(data); > + exit(1); > + } > + > + if(fwrite(data, data_len, 1, fp)!=1) { > + fputs("Error writing output file\n", stderr); > + free(data); > + fclose(fp); > + exit(1); > + } > + > + > + fclose(fp); > + free(data); > + exit(0); > +} > diff --git a/package/utils/caldata-utils/src/caldata.h > b/package/utils/caldata-utils/src/caldata.h > new file mode 100644 > index 0000000..27c8175 > --- /dev/null > +++ b/package/utils/caldata-utils/src/caldata.h > @@ -0,0 +1,42 @@ > + > +/* Documentation */ > +const char *argp_program_version = "caldata utils 1.0"; static char > +doc[] = "caldata - Utility to manipulate calibration data for > +ath10k"; static char args_doc[] = "ARG1 ARG2"; > + > +/* Options */ > +static struct argp_option options[] = { > + {"input", 'i', "PARTITION/FILE", 0, "Read from PARTITION or FILE" }, > + {"output", 'f', "FILE", 0, "Output to FILE." }, > + {"offset", 'o', "BYTES", 0, "Skip first BYTES" }, > + {"size", 's', "BYTES", 0, "Size of data to read"}, > + {"maddress", 'a', "ADDRESS", 0, "new MAC address to assign"}, > + {"verify", 'v', 0, 0, "Only verify input, no output"}, > + { 0 } > +}; > + > +/* Used by main to communicate with parse_opt. */ struct arguments { > + char *input_file; > + char *output_file; > + > + long int offset; > + long int size; > + char *macaddr; > + int newmac[6]; > + > + int verify; > +}; > + > +static error_t parse_opt (int key, char *arg, struct argp_state > +*state); > + > +static struct argp argp = { options, parse_opt, args_doc, doc }; > + > + > +// Utils > + > +int isMAC(char *s); > +int getMTD(char *name); > +unsigned short checksum(void *caldata, int size); > + > diff --git a/package/utils/caldata-utils/src/utils.c > b/package/utils/caldata-utils/src/utils.c > new file mode 100644 > index 0000000..d8bda63 > --- /dev/null > +++ b/package/utils/caldata-utils/src/utils.c > @@ -0,0 +1,72 @@ > +/* > + * > + * Copyright (C) 2016 Adrian Panella <ianchi74@outlook.com> > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License > + * as published by the Free Software Foundation; either version 2 > + * of the License, or (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. > + */ > + > +#include <stdio.h> > +#include <stdlib.h> > +#include <ctype.h> > +#include <string.h> > + > +int isMAC(char *s) { > + int i; > + for(i = 0; i < 17; i++) { > + if(i % 3 != 2 && !isxdigit(s[i])) > + return 0; > + if(i % 3 == 2 && s[i] != ':') > + return 0; > + } > + if(s[17] != '\0') > + return 0; > + return 1; > +} > + > + > +int getMTD(char *name) > +{ > + int device = -1; > + int dev; > + char part[32]; > + FILE *fp = fopen("/proc/mtd", "rb"); > + if (!fp) > + return -1; > + while (!feof(fp) && fscanf(fp, "%*[^0-9]%d: %*s %*s \"%[^\"]\"", &dev, part) == 2) { > + if (!strcmp(part, name)) { > + device = dev; > + break; > + } > + } > + fclose(fp); > + return device; > +} > + > + > +unsigned short checksum(void *caldata, int size) { > + unsigned short *ptr = (unsigned short *)caldata; > + unsigned short crc = 0; > + int i; > + > + for (i = 0; i < size; i += 2) { > + crc ^= *ptr; > + ptr++; > + } > + crc = ~crc; > + return crc; > +} > + > + > -- > 1.9.1 > _______________________________________________ > openwrt-devel mailing list > openwrt-devel@lists.openwrt.org > https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel I'm not convinced this should go into the core packages, but instead to https://github.com/openwrt/packages. - Pushpal
On Donnerstag, 31. März 2016 19:48:20 CET Adrian Panella wrote: > >From df9a676bb3ba225f0fd6621dbaeec945baf3153d Mon Sep 17 00:00:00 2001 > From: Adrian Panella <ianchi74@outlook.com> > Date: Wed, 30 Mar 2016 23:31:06 -0600 > Subject: [PATCH 12/15] caldata-utils: new package to manipulate ath10k > calibration data > > Signed-off-by: Adrian Panella <ianchi74@outlook.com> > --- > package/utils/caldata-utils/Makefile | 60 +++++++++ > package/utils/caldata-utils/src/Makefile | 8 ++ > package/utils/caldata-utils/src/caldata.c | 213 > ++++++++++++++++++++++++++++++ > package/utils/caldata-utils/src/caldata.h | 42 ++++++ > package/utils/caldata-utils/src/utils.c | 72 ++++++++++ > 5 files changed, 395 insertions(+) > create mode 100644 package/utils/caldata-utils/Makefile > create mode 100644 package/utils/caldata-utils/src/Makefile > create mode 100644 package/utils/caldata-utils/src/caldata.c > create mode 100644 package/utils/caldata-utils/src/caldata.h > create mode 100644 package/utils/caldata-utils/src/utils.c I know that the patch submitted here is in a broken state. But was there any decision made what will be done about this problem in general? This will become a problem again on IPQ4019 when somebody must patch the mac address in the pre-cal data. The OTP firmware binary of ath10k will simply reject its content when the checksum in the pre-cal data is incorrect. This reject will happen when the PARAM_FLASH_SECTION_ALL parameter is sent to the OTP [1] (step 4). Instead it will then use the boarddata from board-2.bin which was send to the device in step 3. It is then missing most calibration data which is specific to this single board. Kind regards, Sven [1] https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=3d9195ea19e4854d7daa11688b01905e244aead9
diff --git a/package/utils/caldata-utils/Makefile b/package/utils/caldata-utils/Makefile new file mode 100644 index 0000000..eff7761 --- /dev/null +++ b/package/utils/caldata-utils/Makefile @@ -0,0 +1,60 @@ +# +# Copyright (C) 2006-2010 OpenWrt.org +# Copyright (C) 2016 Adrian Panella +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=caldata-utils +PKG_RELEASE:=1 + +PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) +PKG_BUILD_DEPENDS:=USE_UCLIBC:argp-standalone USE_MUSL:argp-standalone + +include $(INCLUDE_DIR)/package.mk + +ifdef CONFIG_USE_UCLIBC + LIBARGP="-largp" +endif + +ifdef CONFIG_USE_MUSL + LIBARGP="-largp" +endif + + +define Package/caldata-utils + SECTION:=utils + CATEGORY:=Utilities + TITLE:=Utility to manipulate calibration data for ath10k + MAINTAINER:=Adrian Panella <ianchi74@outlook.com> +endef + +define Package/caldata-utils/description + This package contains an utility to manipulate calibration data for ath10k drivers. + It enables to extract from MTD partition or file and to patch MAC address fixing the checksum. +endef + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) + $(CP) ./src/* $(PKG_BUILD_DIR)/ +endef + +define Build/Configure +endef + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR) \ + CC="$(TARGET_CC)" \ + CFLAGS="$(TARGET_CFLAGS) -Wall" \ + LDFLAGS="$(TARGET_LDFLAGS) $(LIBARGP)" +endef + +define Package/caldata-utils/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/caldata $(1)/usr/sbin/ +endef + +$(eval $(call BuildPackage,caldata-utils)) diff --git a/package/utils/caldata-utils/src/Makefile b/package/utils/caldata-utils/src/Makefile new file mode 100644 index 0000000..57ab936 --- /dev/null +++ b/package/utils/caldata-utils/src/Makefile @@ -0,0 +1,8 @@ + +all: caldata + +caldata: caldata.c utils.c + $(CC) $(CFLAGS) -o $@ caldata.c utils.c $(LDFLAGS) + +clean: + rm caldata diff --git a/package/utils/caldata-utils/src/caldata.c b/package/utils/caldata-utils/src/caldata.c new file mode 100644 index 0000000..d5391d5 --- /dev/null +++ b/package/utils/caldata-utils/src/caldata.c @@ -0,0 +1,213 @@ +/* + * + * Copyright (C) 2016 Adrian Panella <ianchi74@outlook.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* + * + * caldata + * + * Utility to manipulate calibration data for ath10k drivers. + * It enables to extract from MTD partition or file and to patch MAC address fixing the checksum. + * + */ + + +#include <stdio.h> +#include <argp.h> +#include <stdlib.h> + +#include "caldata.h" + + +/* Parse a single option. */ +static error_t parse_opt (int key, char *arg, struct argp_state *state) +{ + struct arguments *arguments = state->input; + + switch (key) + { + case 'i': + arguments->input_file = arg; + break; + + case 'f': + arguments->output_file = arg; + break; + + case 'o': + sscanf(arg,"%li", &arguments->offset); + break; + + case 's': + sscanf(arg,"%li", &arguments->size); + break; + + case 'a': + + if(!isMAC(arg)) + argp_error(state,"address is not a valid MAC address"); + + arguments->macaddr = arg; + break; + + case 'v': + arguments->verify = 1; + break; + + case ARGP_KEY_END: //all options processed, verify consistency + + if(!arguments->input_file) + argp_error(state,"No input file or partition specified."); + + if(!arguments->verify && !arguments->output_file) + argp_error(state, "Must specify either -f FILE or -v."); + + break; + + default: + return ARGP_ERR_UNKNOWN; + } + return 0; +} + + +int loadfile(char *file, void **data, int offset, int size) { + *data=NULL; + char *source = NULL; + + + char mtdpath[32]; + FILE *fp=NULL; + + //try input as partition + int mtdnr = getMTD(file); + if(mtdnr>=0) { + sprintf(mtdpath, "/dev/mtdblock%d", mtdnr); + fp = fopen(mtdpath, "rb"); + } + //try as file + if(!fp) + fp = fopen(file, "rb"); + + if (fp != NULL) { + /* Go to the end of the file. */ + if (fseek(fp, 0L, SEEK_END) == 0) { + /* Get the size of the file. */ + long filesize = ftell(fp); + if (filesize == -1) { + fclose(fp); + return -1; } + + size= size ? size : (filesize - offset); + if(size + offset > filesize) { + fputs("Offset + size gets past EOF", stderr); + fclose(fp); + exit(1);} + + source = malloc(size + 1); + + /* offset from the start of the file. */ + if (fseek(fp, offset, SEEK_SET) != 0) { + free(source); + fclose(fp); + return -1;} + + /* Read file into memory. */ + size_t newLen = fread(source, sizeof(char), size, fp); + if (newLen == 0) { + free(source); + fclose(fp); + return -1; + } + else { + fclose(fp); + *data=source; + return size; + } + } + } + return -1; +} + +int main (int argc, char **argv) +{ + struct arguments arguments; + unsigned short ret=0; + + /* Default values. */ + arguments.input_file = NULL; + arguments.output_file = NULL; + arguments.offset = 0; + arguments.size = 0; + arguments.macaddr = NULL; + arguments.verify = 0; + + /* Parse arguments and validate*/ + argp_parse (&argp, argc, argv, 0, 0, &arguments); + + + // read input data + unsigned short *data; + int data_len=loadfile(arguments.input_file,(void **)&data, arguments.offset, arguments.size); + + if(data_len<0) { + fputs("Error reading input file/partition.\n", stderr); + exit(1); + } + + unsigned char *mac=(unsigned char *)data+6; + + if(arguments.verify) { + + printf("Size: %d\n", data[0]); + printf("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + ret=checksum(data, data[0]) ? 1 : 0; + printf("Checksum: 0x%04x (%s)\n", data[1], ret ? "ERROR" : "OK"); + if(ret) + fputs("Calibration data checksum error\n", stderr); + + free(data); + exit(ret); + } + + if(arguments.macaddr) { + sscanf(arguments.macaddr,"%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]); + data[1]=0; + data[1]=checksum(data, data[0]); + } + + FILE *fp=fopen(arguments.output_file,"wb"); + + if(!fp) { + fputs("Error opening output file\n", stderr); + free(data); + exit(1); + } + + if(fwrite(data, data_len, 1, fp)!=1) { + fputs("Error writing output file\n", stderr); + free(data); + fclose(fp); + exit(1); + } + + + fclose(fp); + free(data); + exit(0); +} diff --git a/package/utils/caldata-utils/src/caldata.h b/package/utils/caldata-utils/src/caldata.h new file mode 100644 index 0000000..27c8175 --- /dev/null +++ b/package/utils/caldata-utils/src/caldata.h @@ -0,0 +1,42 @@ + +/* Documentation */ +const char *argp_program_version = "caldata utils 1.0"; +static char doc[] = "caldata - Utility to manipulate calibration data for ath10k"; +static char args_doc[] = "ARG1 ARG2"; + +/* Options */ +static struct argp_option options[] = { + {"input", 'i', "PARTITION/FILE", 0, "Read from PARTITION or FILE" }, + {"output", 'f', "FILE", 0, "Output to FILE." }, + {"offset", 'o', "BYTES", 0, "Skip first BYTES" }, + {"size", 's', "BYTES", 0, "Size of data to read"}, + {"maddress", 'a', "ADDRESS", 0, "new MAC address to assign"}, + {"verify", 'v', 0, 0, "Only verify input, no output"}, + { 0 } +}; + +/* Used by main to communicate with parse_opt. */ +struct arguments +{ + char *input_file; + char *output_file; + + long int offset; + long int size; + char *macaddr; + int newmac[6]; + + int verify; +}; + +static error_t parse_opt (int key, char *arg, struct argp_state *state); + +static struct argp argp = { options, parse_opt, args_doc, doc }; + + +// Utils + +int isMAC(char *s); +int getMTD(char *name); +unsigned short checksum(void *caldata, int size); + diff --git a/package/utils/caldata-utils/src/utils.c b/package/utils/caldata-utils/src/utils.c new file mode 100644 index 0000000..d8bda63 --- /dev/null +++ b/package/utils/caldata-utils/src/utils.c @@ -0,0 +1,72 @@ +/* + * + * Copyright (C) 2016 Adrian Panella <ianchi74@outlook.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> +#include <string.h> + +int isMAC(char *s) { + int i; + for(i = 0; i < 17; i++) { + if(i % 3 != 2 && !isxdigit(s[i])) + return 0; + if(i % 3 == 2 && s[i] != ':') + return 0; + } + if(s[17] != '\0') + return 0; + return 1; +} + + +int getMTD(char *name) +{ + int device = -1; + int dev; + char part[32]; + FILE *fp = fopen("/proc/mtd", "rb"); + if (!fp) + return -1; + while (!feof(fp) && fscanf(fp, "%*[^0-9]%d: %*s %*s \"%[^\"]\"", &dev, part) == 2) { + if (!strcmp(part, name)) { + device = dev; + break; + } + } + fclose(fp); + return device; +} + + +unsigned short checksum(void *caldata, int size) +{ + unsigned short *ptr = (unsigned short *)caldata; + unsigned short crc = 0; + int i; + + for (i = 0; i < size; i += 2) { + crc ^= *ptr; + ptr++; + } + crc = ~crc; + return crc; +}