mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-14 00:24:41 -04:00
msm: ipa: Add new IOCTLs to get and set MTU
Add a new IOCTL that will allow userspace modules to get and set the v4/v6 mtu for a specific rmnet interface for IPA driver and IPACM to use. Change-Id: Iaf0685ef7095960ddd1cd3fff803956a18e0a942 Signed-off-by: Chaitanya Pratapa <cpratapa@codeaurora.org> Signed-off-by: Michael Adisumarta <madisuma@codeaurora.org>
This commit is contained in:
parent
fd8a20143f
commit
7abd8fd060
4 changed files with 241 additions and 0 deletions
|
|
@ -75,6 +75,7 @@ const char *ipa3_event_name[IPA_EVENT_MAX_NUM] = {
|
|||
__stringify(IPA_GSB_DISCONNECT),
|
||||
__stringify(IPA_COALESCE_ENABLE),
|
||||
__stringify(IPA_COALESCE_DISABLE),
|
||||
__stringify(IPA_SET_MTU),
|
||||
__stringify_1(WIGIG_CLIENT_CONNECT),
|
||||
__stringify_1(WIGIG_FST_SWITCH),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -121,6 +121,8 @@ struct ipa3_rmnet_mux_val {
|
|||
bool ul_flt_reg;
|
||||
bool mux_hdr_set;
|
||||
uint32_t hdr_hdl;
|
||||
uint16_t mtu_v4;
|
||||
uint16_t mtu_v6;
|
||||
};
|
||||
|
||||
extern struct qmi_elem_info
|
||||
|
|
@ -305,6 +307,9 @@ int rmnet_ipa3_enable_per_client_stats(bool *data);
|
|||
int rmnet_ipa3_query_per_client_stats(
|
||||
struct wan_ioctl_query_per_client_stats *data);
|
||||
|
||||
int rmnet_ipa3_get_wan_mtu(
|
||||
struct ipa_mtu_info *data);
|
||||
|
||||
int ipa3_qmi_get_data_stats(struct ipa_get_data_stats_req_msg_v01 *req,
|
||||
struct ipa_get_data_stats_resp_msg_v01 *resp);
|
||||
|
||||
|
|
|
|||
|
|
@ -90,6 +90,10 @@ static DECLARE_DELAYED_WORK(ipa_tether_stats_poll_wakequeue_work,
|
|||
static int rmnet_ipa_send_coalesce_notification(uint8_t qmap_id, bool enable,
|
||||
bool tcp, bool udp);
|
||||
|
||||
static int rmnet_ipa_send_set_mtu_notification(char *if_name,
|
||||
uint16_t mtu_v4, uint16_t mtu_v6, enum ipa_ip_type ip);
|
||||
|
||||
|
||||
enum ipa3_wwan_device_status {
|
||||
WWAN_DEVICE_INACTIVE = 0,
|
||||
WWAN_DEVICE_ACTIVE = 1
|
||||
|
|
@ -1756,6 +1760,8 @@ static int ipa3_wwan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
|||
struct mutex *mux_mutex_ptr;
|
||||
int wan_ep;
|
||||
bool tcp_en = false, udp_en = false;
|
||||
bool mtu_v4_set = false, mtu_v6_set = false;
|
||||
enum ipa_ip_type iptype;
|
||||
|
||||
IPAWANDBG("rmnet_ipa got ioctl number 0x%08x", cmd);
|
||||
switch (cmd) {
|
||||
|
|
@ -2086,6 +2092,65 @@ static int ipa3_wwan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
|||
}
|
||||
mutex_unlock(&rmnet_ipa3_ctx->clock_vote.mutex);
|
||||
break;
|
||||
/* Get MTU */
|
||||
case RMNET_IOCTL_GET_MTU:
|
||||
mux_channel = rmnet_ipa3_ctx->mux_channel;
|
||||
rmnet_index =
|
||||
find_vchannel_name_index(ext_ioctl_data.u.mtu_params.if_name);
|
||||
|
||||
if (rmnet_index == MAX_NUM_OF_MUX_CHANNEL) {
|
||||
IPAWANERR("%s is an invalid iface name\n",
|
||||
ext_ioctl_data.u.mtu_params.if_name);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
IPAWANDBG("getting v4 MTU = %d\n", mux_channel[rmnet_index].mtu_v4);
|
||||
ext_ioctl_data.u.mtu_params.mtu_v4 =
|
||||
mux_channel[rmnet_index].mtu_v4;
|
||||
|
||||
IPAWANDBG("getting v6 MTU = %d\n", mux_channel[rmnet_index].mtu_v6);
|
||||
ext_ioctl_data.u.mtu_params.mtu_v6 =
|
||||
mux_channel[rmnet_index].mtu_v6;
|
||||
break;
|
||||
/* Set MTU */
|
||||
case RMNET_IOCTL_SET_MTU:
|
||||
mux_channel = rmnet_ipa3_ctx->mux_channel;
|
||||
rmnet_index =
|
||||
find_vchannel_name_index(ext_ioctl_data.u.mtu_params.if_name);
|
||||
|
||||
if (rmnet_index == MAX_NUM_OF_MUX_CHANNEL) {
|
||||
IPAWANERR("%s is an invalid iface name\n",
|
||||
ext_ioctl_data.u.mtu_params.if_name);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* V4 case */
|
||||
if (ext_ioctl_data.u.mtu_params.mtu_v4 > 0) {
|
||||
mux_channel[rmnet_index].mtu_v4 =
|
||||
ext_ioctl_data.u.mtu_params.mtu_v4;
|
||||
mtu_v4_set = true;
|
||||
IPAWANDBG("Set v4 MTU = %d\n", mux_channel[rmnet_index].mtu_v4);
|
||||
iptype = IPA_IP_v4;
|
||||
}
|
||||
/* V6 case */
|
||||
if (ext_ioctl_data.u.mtu_params.mtu_v6 > 0) {
|
||||
mux_channel[rmnet_index].mtu_v6 =
|
||||
ext_ioctl_data.u.mtu_params.mtu_v6;
|
||||
mtu_v6_set = true;
|
||||
IPAWANDBG("Set v6 MTU = %d\n", mux_channel[rmnet_index].mtu_v6);
|
||||
iptype = IPA_IP_v6;
|
||||
}
|
||||
|
||||
if (mtu_v4_set && mtu_v6_set)
|
||||
iptype = IPA_IP_MAX;
|
||||
|
||||
rc = rmnet_ipa_send_set_mtu_notification(
|
||||
ext_ioctl_data.u.mtu_params.if_name,
|
||||
mux_channel[rmnet_index].mtu_v4,
|
||||
mux_channel[rmnet_index].mtu_v6,
|
||||
iptype);
|
||||
|
||||
break;
|
||||
default:
|
||||
IPAWANERR("[%s] unsupported extended cmd[%d]",
|
||||
dev->name,
|
||||
|
|
@ -2179,6 +2244,37 @@ static int rmnet_ipa_send_coalesce_notification(uint8_t qmap_id,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int rmnet_ipa_send_set_mtu_notification(char *if_name,
|
||||
uint16_t mtu_v4, uint16_t mtu_v6, enum ipa_ip_type ip)
|
||||
{
|
||||
struct ipa_msg_meta msg_meta;
|
||||
struct ipa_mtu_info *mtu_info;
|
||||
int rc;
|
||||
|
||||
memset(&msg_meta, 0, sizeof(struct ipa_msg_meta));
|
||||
mtu_info = kzalloc(sizeof(*mtu_info), GFP_KERNEL);
|
||||
if (!mtu_info)
|
||||
return -ENOMEM;
|
||||
|
||||
strlcpy(mtu_info->if_name, if_name, IPA_RESOURCE_NAME_MAX);
|
||||
mtu_info->mtu_v4 = mtu_v4;
|
||||
mtu_info->mtu_v6 = mtu_v6;
|
||||
mtu_info->ip_type = ip;
|
||||
msg_meta.msg_type = IPA_SET_MTU;
|
||||
msg_meta.msg_len = sizeof(struct ipa_mtu_info);
|
||||
|
||||
rc = ipa_send_msg(&msg_meta, mtu_info, ipa3_wwan_msg_free_cb);
|
||||
if (rc) {
|
||||
IPAWANERR("ipa_send_msg failed: %d\n", rc);
|
||||
return -EFAULT;
|
||||
}
|
||||
IPAWANDBG(
|
||||
"sent new mtu_v4(%d)/mtu_v6(%d) with iptype(%d) for iface(%s) to IPACM",
|
||||
mtu_v4, mtu_v6, ip, if_name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ipa3_wwan_set_modem_state(struct wan_ioctl_notify_wan_state *state)
|
||||
{
|
||||
uint32_t bw_mbps = 0;
|
||||
|
|
@ -4785,13 +4881,118 @@ int rmnet_ipa3_query_per_client_stats(
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* rmnet_ipa3_get_wan_mtu() -
|
||||
* @data - IOCTL data
|
||||
*
|
||||
* This function handles WAN_IOC_GET_WAN_MTU.
|
||||
* It is used to send WAN MTU information to IPACM.
|
||||
*
|
||||
* Return codes:
|
||||
* 0: Success
|
||||
* -EINVAL: Invalid args provided
|
||||
*/
|
||||
int rmnet_ipa3_get_wan_mtu(
|
||||
struct ipa_mtu_info *data)
|
||||
{
|
||||
struct ipa3_rmnet_mux_val *mux_channel;
|
||||
int rmnet_index;
|
||||
|
||||
mux_channel = rmnet_ipa3_ctx->mux_channel;
|
||||
rmnet_index =
|
||||
find_vchannel_name_index(data->if_name);
|
||||
|
||||
if (rmnet_index == MAX_NUM_OF_MUX_CHANNEL) {
|
||||
IPAWANERR("%s is an invalid iface name\n",
|
||||
data->if_name);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
IPAWANDBG("getting v4 MTU = %d\n", mux_channel[rmnet_index].mtu_v4);
|
||||
data->mtu_v4 =
|
||||
mux_channel[rmnet_index].mtu_v4;
|
||||
|
||||
IPAWANDBG("getting v6 MTU = %d\n", mux_channel[rmnet_index].mtu_v6);
|
||||
data->mtu_v6 =
|
||||
mux_channel[rmnet_index].mtu_v6;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
static char dbg_buff[4096];
|
||||
|
||||
static ssize_t rmnet_ipa_set_mtu(struct file *file,
|
||||
const char __user *buf, size_t count, loff_t *ppos)
|
||||
{
|
||||
__s8 if_name[IFNAMSIZ];
|
||||
uint16_t mtu_v4 = 0, mtu_v6 = 0;
|
||||
unsigned long missing;
|
||||
char *sptr, *token;
|
||||
|
||||
if (count >= sizeof(dbg_buff))
|
||||
return -EFAULT;
|
||||
|
||||
missing = copy_from_user(dbg_buff, buf, count);
|
||||
if (missing)
|
||||
return -EFAULT;
|
||||
|
||||
dbg_buff[count] = '\0';
|
||||
|
||||
sptr = dbg_buff;
|
||||
|
||||
memset(if_name, 0, IFNAMSIZ);
|
||||
token = strsep(&sptr, " ");
|
||||
if (!token)
|
||||
return -EINVAL;
|
||||
strlcpy(if_name, token, IFNAMSIZ);
|
||||
|
||||
token = strsep(&sptr, " ");
|
||||
if (!token)
|
||||
return -EINVAL;
|
||||
if (kstrtou16(token, 0, &mtu_v4))
|
||||
return -EINVAL;
|
||||
|
||||
token = strsep(&sptr, " ");
|
||||
if (!token)
|
||||
return -EINVAL;
|
||||
if (kstrtou16(token, 0, &mtu_v6))
|
||||
return -EINVAL;
|
||||
|
||||
rmnet_ipa_send_set_mtu_notification(
|
||||
if_name,
|
||||
mtu_v4,
|
||||
mtu_v6, IPA_IP_MAX);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
#define RMNET_IPA_WRITE_ONLY_MODE 0220
|
||||
|
||||
struct rmnet_ipa_debugfs_file {
|
||||
const char *name;
|
||||
umode_t mode;
|
||||
void *data;
|
||||
const struct file_operations fops;
|
||||
};
|
||||
|
||||
static const struct rmnet_ipa_debugfs_file debugfs_files[] = {
|
||||
{
|
||||
"mtu", RMNET_IPA_WRITE_ONLY_MODE, NULL, {
|
||||
.write = rmnet_ipa_set_mtu,
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
static void rmnet_ipa_debugfs_init(void)
|
||||
{
|
||||
const mode_t read_write_mode = 0664;
|
||||
int i = 0;
|
||||
struct dentry *file;
|
||||
struct rmnet_ipa_debugfs *dbgfs = &rmnet_ipa3_ctx->dbgfs;
|
||||
const size_t debugfs_files_num =
|
||||
sizeof(debugfs_files) / sizeof(struct rmnet_ipa_debugfs_file);
|
||||
|
||||
|
||||
dbgfs->dent = debugfs_create_dir("rmnet_ipa", 0);
|
||||
|
|
@ -4800,6 +5001,18 @@ static void rmnet_ipa_debugfs_init(void)
|
|||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < debugfs_files_num; ++i) {
|
||||
const struct rmnet_ipa_debugfs_file *curr = &debugfs_files[i];
|
||||
|
||||
file = debugfs_create_file(curr->name, curr->mode, dbgfs->dent,
|
||||
curr->data, &curr->fops);
|
||||
if (!file || IS_ERR(file)) {
|
||||
IPAERR("fail to create file for debug_fs %s\n",
|
||||
curr->name);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
dbgfs->dfile_outstanding_high = debugfs_create_u32("outstanding_high",
|
||||
read_write_mode, dbgfs->dent,
|
||||
&rmnet_ipa3_ctx->outstanding_high);
|
||||
|
|
|
|||
|
|
@ -475,6 +475,28 @@ static long ipa3_wan_ioctl(struct file *filp,
|
|||
}
|
||||
break;
|
||||
|
||||
case WAN_IOC_GET_WAN_MTU:
|
||||
IPAWANDBG_LOW("got WAN_IOC_GET_WAN_MTU :>>>\n");
|
||||
pyld_sz = sizeof(struct ipa_mtu_info);
|
||||
param = memdup_user((const void __user *)arg, pyld_sz);
|
||||
if (IS_ERR(param)) {
|
||||
retval = PTR_ERR(param);
|
||||
break;
|
||||
}
|
||||
if (rmnet_ipa3_get_wan_mtu(
|
||||
(struct ipa_mtu_info *)
|
||||
param)) {
|
||||
IPAWANERR("WAN_IOC_GET_WAN_MTU failed\n");
|
||||
retval = -EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
if (copy_to_user((void __user *)arg, param, pyld_sz)) {
|
||||
retval = -EFAULT;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
retval = -ENOTTY;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue