Skip to content

Commit

Permalink
Auto-generate mac address from chipid serial for wifi and ethernet
Browse files Browse the repository at this point in the history
(cherry picked from commit 375c5a3)
  • Loading branch information
ayufan authored and longsleep committed May 1, 2017
1 parent eee28f5 commit c7c5a1f
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 150 deletions.
62 changes: 2 additions & 60 deletions drivers/net/ethernet/allwinner/sunxi-gmac.c
Expand Up @@ -26,6 +26,7 @@
#include <linux/crypto.h>
#include <linux/err.h>
#include <linux/scatterlist.h>
#include <linux/sunxi-sid.h>
#include <linux/regulator/consumer.h>
#include <linux/of_net.h>
#include <linux/io.h>
Expand Down Expand Up @@ -721,63 +722,6 @@ static const struct dev_pm_ops geth_pm_ops;
*
*
****************************************************************************/
#define sunxi_get_soc_chipid(x) {}
static void geth_chip_hwaddr(u8 *addr)
{
#define MD5_SIZE 16
#define CHIP_SIZE 16

struct crypto_hash *tfm;
struct hash_desc desc;
struct scatterlist sg;
u8 result[MD5_SIZE];
u8 chipid[CHIP_SIZE];
int i = 0;
int ret = -1;

memset(chipid, 0, sizeof(chipid));
memset(result, 0, sizeof(result));

sunxi_get_soc_chipid((u8 *)chipid);

tfm = crypto_alloc_hash("md5", 0, CRYPTO_ALG_ASYNC);
if (IS_ERR(tfm)) {
pr_err("Failed to alloc md5\n");
return;
}
desc.tfm = tfm;
desc.flags = 0;

ret = crypto_hash_init(&desc);
if (ret < 0) {
pr_err("crypto_hash_init() failed\n");
goto out;
}

sg_init_one(&sg, chipid, sizeof(chipid) - 1);
ret = crypto_hash_update(&desc, &sg, sizeof(chipid) - 1);
if (ret < 0) {
pr_err("crypto_hash_update() failed for id\n");
goto out;
}

crypto_hash_final(&desc, result);
if (ret < 0) {
pr_err("crypto_hash_final() failed for result\n");
goto out;
}

/* Choose md5 result's [0][2][4][6][8][10] byte as mac address */
for (i = 0; i < ETH_ALEN; i++) {
addr[i] = result[2*i];
}
addr[0] &= 0xfe; /* clear multicast bit */
addr[0] |= 0x02; /* set local assignment bit (IEEE802) */

out:
crypto_free_hash(tfm);
}

static void geth_check_addr(struct net_device *ndev, unsigned char *mac)
{
int i;
Expand All @@ -787,11 +731,9 @@ static void geth_check_addr(struct net_device *ndev, unsigned char *mac)
for (i=0; i<ETH_ALEN; i++, p++)
ndev->dev_addr[i] = simple_strtoul(p, &p, 16);

#if 0
if (!is_valid_ether_addr(ndev->dev_addr)) {
geth_chip_hwaddr(ndev->dev_addr);
sunxi_get_chipid_mac_addr(ndev->dev_addr);
}
#endif

if (!is_valid_ether_addr(ndev->dev_addr)) {
random_ether_addr(ndev->dev_addr);
Expand Down
60 changes: 2 additions & 58 deletions drivers/net/ethernet/allwinner/sunxi-gmac_100.c
Expand Up @@ -26,6 +26,7 @@
#include <linux/crypto.h>
#include <linux/err.h>
#include <linux/scatterlist.h>
#include <linux/sunxi-sid.h>
#include <linux/regulator/consumer.h>
#include <linux/of_net.h>
#include <linux/io.h>
Expand Down Expand Up @@ -733,63 +734,6 @@ static const struct dev_pm_ops geth_pm_ops;
*
*
****************************************************************************/
#define sunxi_get_soc_chipid(x) {}
static void geth_chip_hwaddr(u8 *addr)
{
#define MD5_SIZE 16
#define CHIP_SIZE 16

struct crypto_hash *tfm;
struct hash_desc desc;
struct scatterlist sg;
u8 result[MD5_SIZE];
u8 chipid[CHIP_SIZE];
int i = 0;
int ret = -1;

memset(chipid, 0, sizeof(chipid));
memset(result, 0, sizeof(result));

sunxi_get_soc_chipid((u8 *)chipid);

tfm = crypto_alloc_hash("md5", 0, CRYPTO_ALG_ASYNC);
if (IS_ERR(tfm)) {
pr_err("Failed to alloc md5\n");
return;
}
desc.tfm = tfm;
desc.flags = 0;

ret = crypto_hash_init(&desc);
if (ret < 0) {
pr_err("crypto_hash_init() failed\n");
goto out;
}

sg_init_one(&sg, chipid, sizeof(chipid) - 1);
ret = crypto_hash_update(&desc, &sg, sizeof(chipid) - 1);
if (ret < 0) {
pr_err("crypto_hash_update() failed for id\n");
goto out;
}

crypto_hash_final(&desc, result);
if (ret < 0) {
pr_err("crypto_hash_final() failed for result\n");
goto out;
}

/* Choose md5 result's [0][2][4][6][8][10] byte as mac address */
for (i = 0; i < ETH_ALEN; i++) {
addr[i] = result[2*i];
}
addr[0] &= 0xfe; /* clear multicast bit */
addr[0] |= 0x02; /* set local assignment bit (IEEE802) */

out:
crypto_free_hash(tfm);
}

static void geth_check_addr(struct net_device *ndev, unsigned char *mac)
{
int i;
Expand All @@ -800,7 +744,7 @@ static void geth_check_addr(struct net_device *ndev, unsigned char *mac)
ndev->dev_addr[i] = simple_strtoul(p, &p, 16);

if (!is_valid_ether_addr(ndev->dev_addr)) {
geth_chip_hwaddr(ndev->dev_addr);
sunxi_get_chipid_mac_addr(ndev->dev_addr);
}

if (!is_valid_ether_addr(ndev->dev_addr)) {
Expand Down
16 changes: 3 additions & 13 deletions drivers/net/wireless/rtl8189fs/core/rtw_ieee80211.c
Expand Up @@ -23,7 +23,7 @@
#include <linux/fs.h>
#endif
#include <drv_types.h>

#include <linux/sunxi-sid.h>

u8 RTW_WPA_OUI_TYPE[] = { 0x00, 0x50, 0xf2, 1 };
u16 RTW_WPA_VERSION = 1;
Expand Down Expand Up @@ -1508,21 +1508,11 @@ void rtw_macaddr_cfg(u8 *out, const u8 *hw_mac_addr)

err_chk:
if (rtw_check_invalid_mac_address(mac, _TRUE) == _TRUE) {
#if DEFAULT_RANDOM_MACADDR
DBG_871X_LEVEL(_drv_err_, "invalid mac addr:"MAC_FMT", assign random MAC\n", MAC_ARG(mac));
*((u32 *)(&mac[2])) = rtw_random32();
DBG_871X_LEVEL(_drv_err_, "invalid mac addr:"MAC_FMT", assign chipid MAC\n", MAC_ARG(mac));
sunxi_get_chipid_mac_addr(mac);
mac[0] = 0x00;
mac[1] = 0xe0;
mac[2] = 0x4c;
#else
DBG_871X_LEVEL(_drv_err_, "invalid mac addr:"MAC_FMT", assign default one\n", MAC_ARG(mac));
mac[0] = 0x00;
mac[1] = 0xe0;
mac[2] = 0x4c;
mac[3] = 0x87;
mac[4] = 0x00;
mac[5] = 0x00;
#endif
}

_rtw_memcpy(out, mac, ETH_ALEN);
Expand Down
9 changes: 3 additions & 6 deletions drivers/net/wireless/rtl8723bs/core/rtw_ieee80211.c
Expand Up @@ -23,6 +23,7 @@
#include <linux/fs.h>
#endif
#include <drv_types.h>
#include <linux/sunxi-sid.h>


u8 RTW_WPA_OUI_TYPE[] = { 0x00, 0x50, 0xf2, 1 };
Expand Down Expand Up @@ -1467,15 +1468,11 @@ void rtw_macaddr_cfg(u8 *out, const u8 *hw_mac_addr)

err_chk:
if (rtw_check_invalid_mac_address(mac) == _TRUE) {
DBG_871X_LEVEL(_drv_err_, "invalid mac addr:"MAC_FMT", assign default one!!!\n", MAC_ARG(mac));

/* use default mac address */
DBG_871X_LEVEL(_drv_err_, "invalid mac addr:"MAC_FMT", assign chipid MAC\n", MAC_ARG(mac));
sunxi_get_chipid_mac_addr(mac);
mac[0] = 0x00;
mac[1] = 0xe0;
mac[2] = 0x4c;
mac[3] = 0x87;
mac[4] = 0x00;
mac[5] = 0x00;
}

_rtw_memcpy(out, mac, ETH_ALEN);
Expand Down
16 changes: 3 additions & 13 deletions drivers/net/wireless/rtl8723cs/core/rtw_ieee80211.c
Expand Up @@ -23,7 +23,7 @@
#include <linux/fs.h>
#endif
#include <drv_types.h>

#include <linux/sunxi-sid.h>

u8 RTW_WPA_OUI_TYPE[] = { 0x00, 0x50, 0xf2, 1 };
u16 RTW_WPA_VERSION = 1;
Expand Down Expand Up @@ -1517,21 +1517,11 @@ void rtw_macaddr_cfg(u8 *out, const u8 *hw_mac_addr)

err_chk:
if (rtw_check_invalid_mac_address(mac, _TRUE) == _TRUE) {
#if DEFAULT_RANDOM_MACADDR
DBG_871X_LEVEL(_drv_err_, "invalid mac addr:"MAC_FMT", assign random MAC\n", MAC_ARG(mac));
*((u32 *)(&mac[2])) = rtw_random32();
DBG_871X_LEVEL(_drv_err_, "invalid mac addr:"MAC_FMT", assign chipid MAC\n", MAC_ARG(mac));
sunxi_get_chipid_mac_addr(mac);
mac[0] = 0x00;
mac[1] = 0xe0;
mac[2] = 0x4c;
#else
DBG_871X_LEVEL(_drv_err_, "invalid mac addr:"MAC_FMT", assign default one\n", MAC_ARG(mac));
mac[0] = 0x00;
mac[1] = 0xe0;
mac[2] = 0x4c;
mac[3] = 0x87;
mac[4] = 0x00;
mac[5] = 0x00;
#endif
}

_rtw_memcpy(out, mac, ETH_ALEN);
Expand Down
53 changes: 53 additions & 0 deletions drivers/soc/allwinner/sunxi-sid.c
Expand Up @@ -21,6 +21,8 @@
#include <linux/of_address.h>
#include <linux/err.h>
#include <linux/sunxi-smc.h>
#include <linux/crypto.h>
#include <linux/scatterlist.h>

#include <linux/sunxi-sid.h>
#include "sunxi-sid-efuse.h"
Expand Down Expand Up @@ -570,3 +572,54 @@ s32 sunxi_efuse_readn(void *key_name, void *buf, u32 n)
}
EXPORT_SYMBOL(sunxi_efuse_readn);

int sunxi_get_chipid_mac_addr(u8 *addr)
{
#define MD5_SIZE 16

struct crypto_hash *tfm;
struct hash_desc desc;
struct scatterlist sg;
u8 result[MD5_SIZE];
int i = 0;
int ret = -1;

sid_chipid_init();

tfm = crypto_alloc_hash("md5", 0, CRYPTO_ALG_ASYNC);
if (IS_ERR(tfm)) {
pr_err("Failed to alloc md5\n");
return;
}
desc.tfm = tfm;
desc.flags = 0;

ret = crypto_hash_init(&desc);
if (ret < 0) {
pr_err("crypto_hash_init() failed\n");
goto out;
}

sg_init_one(&sg, sunxi_soc_chipid, sizeof(sunxi_soc_chipid) - 1);
ret = crypto_hash_update(&desc, &sg, sizeof(sunxi_soc_chipid) - 1);
if (ret < 0) {
pr_err("crypto_hash_update() failed for id\n");
goto out;
}

crypto_hash_final(&desc, result);
if (ret < 0) {
pr_err("crypto_hash_final() failed for result\n");
goto out;
}

/* Choose md5 result's [0][2][4][6][8][10] byte as mac address */
for (i = 0; i < 6; i++) {
addr[i] = result[2*i];
}
addr[0] &= 0xfe; /* clear multicast bit */
addr[0] |= 0x02; /* set local assignment bit (IEEE802) */

out:
crypto_free_hash(tfm);
}
EXPORT_SYMBOL(sunxi_get_chipid_mac_addr);

0 comments on commit c7c5a1f

Please sign in to comment.