mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 03:01:39 -04:00
usb: f_gsi: Allow user to specify MAC address for RNDIS/ECM
Currently driver uses random MAC address which gets changed across composition switches or reboots. Allow user to specify MAC address using configfs parameter to fix this. Change-Id: I96710b3419ff7c016b931195a80ce77cd8c9038c Signed-off-by: Manu Gautam <[email protected]>
This commit is contained in:
parent
28255001cf
commit
c6585c886a
2 changed files with 101 additions and 10 deletions
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
|
@ -2859,6 +2859,26 @@ static void ipa_ready_callback(void *user_data)
|
|||
wake_up_interruptible(&gsi->d_port.wait_for_ipa_ready);
|
||||
}
|
||||
|
||||
static void gsi_get_ether_addr(const char *str, u8 *dev_addr)
|
||||
{
|
||||
if (str) {
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < ETH_ALEN; i++) {
|
||||
unsigned char num;
|
||||
|
||||
if ((*str == '.') || (*str == ':'))
|
||||
str++;
|
||||
num = hex_to_bin(*str++) << 4;
|
||||
num |= hex_to_bin(*str++);
|
||||
dev_addr[i] = num;
|
||||
}
|
||||
if (is_valid_ether_addr(dev_addr))
|
||||
return;
|
||||
}
|
||||
random_ether_addr(dev_addr);
|
||||
}
|
||||
|
||||
static int gsi_bind(struct usb_configuration *c, struct usb_function *f)
|
||||
{
|
||||
struct usb_composite_dev *cdev = c->cdev;
|
||||
|
|
@ -2933,11 +2953,15 @@ static int gsi_bind(struct usb_configuration *c, struct usb_function *f)
|
|||
rndis_set_param_medium(gsi->params, RNDIS_MEDIUM_802_3, 0);
|
||||
|
||||
/* export host's Ethernet address in CDC format */
|
||||
random_ether_addr(gsi->d_port.ipa_init_params.device_ethaddr);
|
||||
random_ether_addr(gsi->d_port.ipa_init_params.host_ethaddr);
|
||||
gsi_get_ether_addr(gsi->dev_addr,
|
||||
gsi->d_port.ipa_init_params.device_ethaddr);
|
||||
|
||||
gsi_get_ether_addr(gsi->host_addr,
|
||||
gsi->d_port.ipa_init_params.host_ethaddr);
|
||||
|
||||
log_event_dbg("setting host_ethaddr=%pM, device_ethaddr = %pM",
|
||||
gsi->d_port.ipa_init_params.host_ethaddr,
|
||||
gsi->d_port.ipa_init_params.device_ethaddr);
|
||||
gsi->d_port.ipa_init_params.host_ethaddr,
|
||||
gsi->d_port.ipa_init_params.device_ethaddr);
|
||||
memcpy(gsi->ethaddr, &gsi->d_port.ipa_init_params.host_ethaddr,
|
||||
ETH_ALEN);
|
||||
rndis_set_host_mac(gsi->params, gsi->ethaddr);
|
||||
|
|
@ -3138,11 +3162,15 @@ static int gsi_bind(struct usb_configuration *c, struct usb_function *f)
|
|||
info.notify_buf_len = GSI_CTRL_NOTIFY_BUFF_LEN;
|
||||
|
||||
/* export host's Ethernet address in CDC format */
|
||||
random_ether_addr(gsi->d_port.ipa_init_params.device_ethaddr);
|
||||
random_ether_addr(gsi->d_port.ipa_init_params.host_ethaddr);
|
||||
gsi_get_ether_addr(gsi->dev_addr,
|
||||
gsi->d_port.ipa_init_params.device_ethaddr);
|
||||
|
||||
gsi_get_ether_addr(gsi->host_addr,
|
||||
gsi->d_port.ipa_init_params.host_ethaddr);
|
||||
|
||||
log_event_dbg("setting host_ethaddr=%pM, device_ethaddr = %pM",
|
||||
gsi->d_port.ipa_init_params.host_ethaddr,
|
||||
gsi->d_port.ipa_init_params.device_ethaddr);
|
||||
gsi->d_port.ipa_init_params.host_ethaddr,
|
||||
gsi->d_port.ipa_init_params.device_ethaddr);
|
||||
|
||||
snprintf(gsi->ethaddr, sizeof(gsi->ethaddr),
|
||||
"%02X%02X%02X%02X%02X%02X",
|
||||
|
|
@ -3578,9 +3606,53 @@ static ssize_t gsi_rndis_class_id_store(struct config_item *item,
|
|||
}
|
||||
CONFIGFS_ATTR(gsi_, rndis_class_id);
|
||||
|
||||
static ssize_t gsi_host_addr_show(struct config_item *item, char *page)
|
||||
{
|
||||
struct f_gsi *gsi = to_gsi_opts(item)->gsi;
|
||||
|
||||
return scnprintf(page, PAGE_SIZE, "%s\n", gsi->host_addr);
|
||||
}
|
||||
|
||||
static ssize_t gsi_host_addr_store(struct config_item *item,
|
||||
const char *page, size_t len)
|
||||
{
|
||||
struct f_gsi *gsi = to_gsi_opts(item)->gsi;
|
||||
|
||||
if (len > GSI_MAX_MAC_ADDR_LEN)
|
||||
return -EINVAL;
|
||||
|
||||
strlcpy(gsi->host_addr, page, GSI_MAX_MAC_ADDR_LEN);
|
||||
|
||||
return len;
|
||||
}
|
||||
CONFIGFS_ATTR(gsi_, host_addr);
|
||||
|
||||
static ssize_t gsi_dev_addr_show(struct config_item *item, char *page)
|
||||
{
|
||||
struct f_gsi *gsi = to_gsi_opts(item)->gsi;
|
||||
|
||||
return scnprintf(page, PAGE_SIZE, "%s\n", gsi->dev_addr);
|
||||
}
|
||||
|
||||
static ssize_t gsi_dev_addr_store(struct config_item *item,
|
||||
const char *page, size_t len)
|
||||
{
|
||||
struct f_gsi *gsi = to_gsi_opts(item)->gsi;
|
||||
|
||||
if (len > GSI_MAX_MAC_ADDR_LEN)
|
||||
return -EINVAL;
|
||||
|
||||
strlcpy(gsi->dev_addr, page, GSI_MAX_MAC_ADDR_LEN);
|
||||
|
||||
return len;
|
||||
}
|
||||
CONFIGFS_ATTR(gsi_, dev_addr);
|
||||
|
||||
static struct configfs_attribute *gsi_rndis_attrs[] = {
|
||||
&gsi_attr_info,
|
||||
&gsi_attr_rndis_class_id,
|
||||
&gsi_attr_host_addr,
|
||||
&gsi_attr_dev_addr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
|
@ -3590,6 +3662,18 @@ static struct config_item_type gsi_func_rndis_type = {
|
|||
.ct_owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static struct configfs_attribute *gsi_ecm_attrs[] = {
|
||||
&gsi_attr_host_addr,
|
||||
&gsi_attr_dev_addr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct config_item_type gsi_func_ecm_type = {
|
||||
.ct_item_ops = &gsi_item_ops,
|
||||
.ct_attrs = gsi_ecm_attrs,
|
||||
.ct_owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static void gsi_inst_clean(struct gsi_opts *opts)
|
||||
{
|
||||
if (opts->gsi->c_port.cdev.dev) {
|
||||
|
|
@ -3642,6 +3726,10 @@ static int gsi_set_inst_name(struct usb_function_instance *fi,
|
|||
config_group_init_type_name(&opts->func_inst.group,
|
||||
fi->group.cg_item.ci_name,
|
||||
&gsi_func_rndis_type);
|
||||
if (prot_id == IPA_USB_ECM)
|
||||
config_group_init_type_name(&opts->func_inst.group,
|
||||
fi->group.cg_item.ci_name,
|
||||
&gsi_func_ecm_type);
|
||||
|
||||
gsi = gsi_function_init(prot_id);
|
||||
if (IS_ERR(gsi))
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _F_GSI_H
|
||||
|
|
@ -28,6 +28,7 @@
|
|||
#define GSI_CTRL_NAME_LEN (sizeof(GSI_MBIM_CTRL_NAME)+2)
|
||||
#define GSI_MAX_CTRL_PKT_SIZE 8192
|
||||
#define GSI_CTRL_DTR (1 << 0)
|
||||
#define GSI_MAX_MAC_ADDR_LEN 18
|
||||
|
||||
#define GSI_NUM_IN_RNDIS_BUFFERS 50
|
||||
#define GSI_NUM_IN_RMNET_BUFFERS 50
|
||||
|
|
@ -264,6 +265,8 @@ struct f_gsi {
|
|||
u32 vendorID;
|
||||
u8 ethaddr[ETH_ADDR_STR_LEN];
|
||||
const char *manufacturer;
|
||||
char host_addr[GSI_MAX_MAC_ADDR_LEN];
|
||||
char dev_addr[GSI_MAX_MAC_ADDR_LEN];
|
||||
struct rndis_params *params;
|
||||
atomic_t connected;
|
||||
bool data_interface_up;
|
||||
|
|
|
|||
Loading…
Reference in a new issue