board: nexell: add MAC Generator feature
authorJaewon Kim <jaewon02.kim@samsung.com>
Tue, 23 May 2017 08:10:39 +0000 (17:10 +0900)
committerJaewon Kim <jaewon02.kim@samsung.com>
Thu, 8 Jun 2017 12:10:46 +0000 (21:10 +0900)
This patch adds MAC generator feature.
MAC generated using artik unique serial number.

Change-Id: I6ff56c53c7f916c8d1ef3827a954e78908393492
Signed-off-by: Jaewon Kim <jaewon02.kim@samsung.com>
board/nexell/common/Makefile
board/nexell/common/mac.c [new file with mode: 0644]
include/artik_mac.h [new file with mode: 0644]

index d4ea16eee63b2ecf78ecd93a77fc50da3cecd99f..b1fe1692e49726026aefb389f14a7ee7db777a5f 100644 (file)
@@ -6,3 +6,4 @@
 #
 
 obj-$(CONFIG_ARTIK_OTA)                += ota.o
+obj-$(CONFIG_ARTIK_MAC)                += mac.o
diff --git a/board/nexell/common/mac.c b/board/nexell/common/mac.c
new file mode 100644 (file)
index 0000000..341cea4
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics
+ * Author: Jaewon Kim <jaewon02.kim@samsung.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <linux/ctype.h>
+#include <artik_mac.h>
+
+#define ARTIK_A710             "710"
+#define ARTIK_A530             "530"
+#define CMD_MAX                        256
+#define GET_YEAR_FROM_SN(x)    (((x) - 'B') + 2016)
+
+static const struct artik_info_t artik_info[] = {
+       {
+               /* Artik710 */
+               .board_name     = ARTIK_A710,
+               .year_offset    = 2016,
+               .security       = '0',
+               .model_code     = 0,
+               .oui            = 0x00ABC1,     /* FIXME: Temporary OUI */
+       }, {
+               /* Artik710s */
+               .board_name     = ARTIK_A710,
+               .year_offset    = 2016,
+               .security       = 'L',
+               .model_code     = 1,
+               .oui            = 0x00ABC2,     /* FIXME: Temporary OUI */
+       }, {
+               /* Artik530 */
+               .board_name     = ARTIK_A530,
+               .year_offset    = 2016,
+               .security       = '0',
+               .model_code     = 2,
+               .oui            = 0x00ABC3,     /* FIXME: Temporary OUI */
+       }, {
+               /* Artik530s */
+               .board_name     = ARTIK_A530,
+               .year_offset    = 2016,
+               .security       = 'L',
+               .model_code     = 3,
+               .oui            = 0x00ABC4,     /* FIXME: Temporary OUI */
+       },
+       { },
+};
+
+static const struct artik_info_t *get_board_info(
+               const int year, const char *name, const char *security)
+{
+       const struct artik_info_t *info = &artik_info[0];
+       int year_field;
+
+       while (info->board_name != NULL) {
+               year_field = year - info->year_offset;
+               if (year_field < 0 || year_field > 4) {
+                       info++;
+                       continue;
+               }
+
+               if (strncmp(info->board_name, name, 3) == 0 &&
+                               strncmp(&info->security, security, 1) == 0)
+                       return info;
+               info++;
+       }
+
+       return NULL;
+}
+
+static int convert_number(const char *cp, size_t len)
+{
+       int value, result = 0;
+
+       while (len-- > 0) {
+               if (isdigit(*cp)) {
+                       value = *cp - '0';
+               } else if (isupper(*cp)) {
+                       value = *cp - 'A' + 10;
+               } else {
+                       printf("Artik MAC : Unsupported Type(%c)\n", *cp);
+                       return -EINVAL;
+               }
+
+               result = (result * 10) + value;
+               cp++;
+       }
+
+       return result;
+}
+
+void generate_mac(void)
+{
+       const struct artik_info_t *info;
+       struct serial_t *serial;
+       char *ethaddr, *artik_serial;
+       char env_var[CMD_MAX] = {0, };
+       int val;
+       u32 mac = 0;
+
+       /* Check ethernet mac address */
+       ethaddr = getenv("ethaddr");
+       if (ethaddr != NULL)
+               return;
+
+       /* Check artik serial number.
+        * If there is no serial number, generate random mac address.
+        */
+       artik_serial = getenv("serial#");
+       if (artik_serial == NULL)
+               return;
+       serial = (struct serial_t *)artik_serial;
+
+       /* Get board type */
+       info = get_board_info(GET_YEAR_FROM_SN(serial->year[0]),
+                       serial->model, serial->security);
+       if (info == NULL)
+               return;
+       mac = SET_MODEL_FIELD(info->model_code);
+
+       /* Convert Year */
+       mac |= SET_YEAR_FIELD(
+                       GET_YEAR_FROM_SN(serial->year[0]) - info->year_offset);
+
+       /* Convert Month */
+       val = convert_number(serial->month, 1);
+       if (val < 0)
+               return;
+       mac |= SET_MONTH_FIELD(val);
+
+       /* Convert Day */
+       val = convert_number(serial->day, 1);
+       if (val < 0)
+               return;
+       mac |= SET_DAY_FIELD(val);
+
+       /* Convert Serial */
+       val = convert_number(serial->serial, 4);
+       if (val < 0)
+               return;
+       mac |= SET_SERIAL_FILED(val);
+
+       /* Set MAC Address */
+       snprintf(env_var, CMD_MAX, "%x:%x:%x:%x:%x:%x",
+                       MAC_ADDR_2(info->oui), MAC_ADDR_1(info->oui),
+                       MAC_ADDR_0(info->oui), MAC_ADDR_2(mac),
+                       MAC_ADDR_1(mac), MAC_ADDR_0(mac));
+       setenv("ethaddr", env_var);
+}
diff --git a/include/artik_mac.h b/include/artik_mac.h
new file mode 100644 (file)
index 0000000..3fd6f71
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics
+ * Author: Jaewon Kim <jaewon02.kim@samsung.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef __ARTIK_MAC_H
+#define __ARTIK_MAC_H
+
+#define SET_YEAR_FIELD(x)      (((x) & 0x3) << 22)
+#define SET_MONTH_FIELD(x)     (((x) & 0xF) << 18)
+#define SET_DAY_FIELD(x)       (((x) & 0x1F) << 13)
+#define SET_MODEL_FIELD(x)     (((x) & 0x3) << 11)
+#define SET_SERIAL_FILED(x)    (((x) & 0x7FF))
+
+#define MAC_ADDR_0(x)          (((x) >> 0) & 0xFF)
+#define MAC_ADDR_1(x)          (((x) >> 8) & 0xFF)
+#define MAC_ADDR_2(x)          (((x) >> 16) & 0xFF)
+
+struct serial_t {
+       char model[3];
+       char sub[1];
+       char assy[1];
+       char year[1];
+       char month[1];
+       char day[1];
+       char hw_version[3];
+       char security[1];
+       char serial[4];
+};
+
+struct artik_info_t {
+       const char *board_name;
+       const char security;
+       const u32 year_offset;
+       const u32 model_code;
+       const u32 oui;
+};
+
+void generate_mac(void);
+#endif