[OpenWrt-Devel] [PATCH 4/8] caldata-utils: new package to manipulate ath10k
Adrian Panella
ianchi74 at outlook.com
Fri Apr 1 16:01:50 EDT 2016
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 at 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 at outlook.com> wrote:
>
>
> From df9a676bb3ba225f0fd6621dbaeec945baf3153d Mon Sep 17 00:00:00 2001
> From: Adrian Panella <ianchi74 at 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 at 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 at 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 at 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 at 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 at 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
_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel
More information about the openwrt-devel
mailing list