Loading drivers/platform/msm/ipa/ipa_clients/ipa_wigig.c +162 −14 Original line number Diff line number Diff line Loading @@ -62,6 +62,7 @@ struct ipa_wigig_context { struct ipa_wigig_rx_pipe_data_buffer_info_smmu rx_buff_smmu; struct ipa_wigig_tx_pipe_data_buffer_info_smmu tx_buff_smmu[IPA_WIGIG_TX_PIPE_NUM]; char clients_mac[IPA_WIGIG_TX_PIPE_NUM][IPA_MAC_ADDR_SIZE]; }; static struct ipa_wigig_context *ipa_wigig_ctx; Loading Loading @@ -216,35 +217,85 @@ static void ipa_wigig_free_msg(void *msg, uint32_t len, uint32_t type) IPA_WIGIG_DBG("exit\n"); } static int ipa_wigig_send_msg(uint8_t msg_type, const char *netdev_name, u8 *netdev_mac) static int ipa_wigig_send_wlan_msg(enum ipa_wlan_event msg_type, const char *netdev_name, u8 *mac) { struct ipa_msg_meta msg_meta; struct ipa_wlan_msg *msg; struct ipa_wlan_msg *wlan_msg; int ret; IPA_WIGIG_DBG("\n"); IPA_WIGIG_DBG("%d\n", msg_type); msg_meta.msg_type = msg_type; wlan_msg = kzalloc(sizeof(*wlan_msg), GFP_KERNEL); if (wlan_msg == NULL) return -ENOMEM; strlcpy(wlan_msg->name, netdev_name, IPA_RESOURCE_NAME_MAX); memcpy(wlan_msg->mac_addr, mac, IPA_MAC_ADDR_SIZE); msg_meta.msg_len = sizeof(struct ipa_wlan_msg); msg_meta.msg_type = msg_type; IPA_WIGIG_DBG("send msg type:%d, len:%d, buff %pK", msg_meta.msg_type, msg_meta.msg_len, wlan_msg); ret = ipa_send_msg(&msg_meta, wlan_msg, ipa_wigig_free_msg); IPA_WIGIG_DBG("exit\n"); return ret; } int ipa_wigig_send_msg(int msg_type, const char *netdev_name, u8 *mac, enum ipa_client_type client, bool to_wigig) { struct ipa_msg_meta msg_meta; struct ipa_wigig_msg *wigig_msg; int ret; msg = kzalloc(sizeof(*msg), GFP_KERNEL); if (msg == NULL) IPA_WIGIG_DBG("\n"); wigig_msg = kzalloc(sizeof(struct ipa_wigig_msg), GFP_KERNEL); if (wigig_msg == NULL) return -ENOMEM; strlcpy(wigig_msg->name, netdev_name, IPA_RESOURCE_NAME_MAX); memcpy(wigig_msg->client_mac_addr, mac, IPA_MAC_ADDR_SIZE); if (msg_type == WIGIG_CLIENT_CONNECT) wigig_msg->u.ipa_client = client; else wigig_msg->u.to_wigig = to_wigig; strlcpy(msg->name, netdev_name, IPA_RESOURCE_NAME_MAX); memcpy(msg->mac_addr, netdev_mac, IPA_MAC_ADDR_SIZE); msg_meta.msg_type = msg_type; msg_meta.msg_len = sizeof(struct ipa_wigig_msg); IPA_WIGIG_DBG("send msg type:%d, len:%d, buff %pK", msg_meta.msg_type, msg_meta.msg_len, msg); ret = ipa_send_msg(&msg_meta, msg, ipa_wigig_free_msg); msg_meta.msg_len, wigig_msg); ret = ipa_send_msg(&msg_meta, wigig_msg, ipa_wigig_free_msg); IPA_WIGIG_DBG("exit\n"); return ret; } static int ipa_wigig_get_devname(char *netdev_name) { struct ipa_wigig_intf_info *entry; mutex_lock(&ipa_wigig_ctx->lock); if (!list_is_singular(&ipa_wigig_ctx->head_intf_list)) { IPA_WIGIG_DBG("list is not singular, was an IF registered?\n"); mutex_unlock(&ipa_wigig_ctx->lock); return -EFAULT; } entry = list_first_entry(&ipa_wigig_ctx->head_intf_list, struct ipa_wigig_intf_info, link); strlcpy(netdev_name, entry->netdev_name, IPA_RESOURCE_NAME_MAX); mutex_unlock(&ipa_wigig_ctx->lock); return 0; } int ipa_wigig_reg_intf( struct ipa_wigig_reg_intf_in_params *in) { Loading Loading @@ -359,7 +410,7 @@ int ipa_wigig_reg_intf( goto fail_register; } if (ipa_wigig_send_msg(WLAN_AP_CONNECT, if (ipa_wigig_send_wlan_msg(WLAN_AP_CONNECT, in->netdev_name, in->netdev_mac)) { IPA_WIGIG_ERR("couldn't send msg to IPACM\n"); Loading Loading @@ -453,7 +504,7 @@ int ipa_wigig_dereg_intf(const char *netdev_name) goto fail; } if (ipa_wigig_send_msg(WLAN_AP_DISCONNECT, if (ipa_wigig_send_wlan_msg(WLAN_AP_DISCONNECT, entry->netdev_name, entry->netdev_mac)) { IPA_WIGIG_ERR("couldn't send msg to IPACM\n"); Loading Loading @@ -1088,9 +1139,43 @@ int ipa_wigig_set_perf_profile(u32 max_supported_bw_mbps) } EXPORT_SYMBOL(ipa_wigig_set_perf_profile); static int ipa_wigig_store_client_mac(enum ipa_client_type client, const char *mac) { unsigned int idx; if (ipa_wigig_client_to_idx(client, &idx)) { IPA_WIGIG_ERR("couldn't acquire idx\n"); return -EFAULT; } memcpy(ipa_wigig_ctx->clients_mac[idx - 1], mac, IPA_MAC_ADDR_SIZE); return 0; } static int ipa_wigig_get_client_mac(enum ipa_client_type client, char *mac) { unsigned int idx; if (ipa_wigig_client_to_idx(client, &idx)) { IPA_WIGIG_ERR("couldn't acquire idx\n"); return -EFAULT; } memcpy(mac, ipa_wigig_ctx->clients_mac[idx - 1], IPA_MAC_ADDR_SIZE); return 0; } static int ipa_wigig_clean_client_mac(enum ipa_client_type client) { char zero_mac[IPA_MAC_ADDR_SIZE] = { 0 }; return ipa_wigig_store_client_mac(client, zero_mac); } int ipa_wigig_conn_client(struct ipa_wigig_conn_tx_in_params *in, struct ipa_wigig_conn_out_params *out) { char dev_name[IPA_RESOURCE_NAME_MAX]; IPA_WIGIG_DBG("\n"); if (!in || !out) { Loading @@ -1113,6 +1198,11 @@ int ipa_wigig_conn_client(struct ipa_wigig_conn_tx_in_params *in, return -EFAULT; } if (ipa_wigig_get_devname(dev_name)) { IPA_WIGIG_ERR("couldn't get dev name\n"); return -EFAULT; } if (ipa_conn_wigig_client_i(in, out)) { IPA_WIGIG_ERR( "fail to connect client. MAC [%X][%X][%X][%X][%X][%X]\n" Loading @@ -1121,8 +1211,20 @@ int ipa_wigig_conn_client(struct ipa_wigig_conn_tx_in_params *in, return -EFAULT; } if (ipa_wigig_send_msg(WIGIG_CLIENT_CONNECT, dev_name, in->client_mac, out->client, false)) { IPA_WIGIG_ERR("couldn't send msg to IPACM\n"); goto fail_sendmsg; } ipa_wigig_store_client_mac(out->client, in->client_mac); IPA_WIGIG_DBG("exit\n"); return 0; fail_sendmsg: ipa_disconn_wigig_pipe_i(out->client, NULL, NULL); return -EFAULT; } EXPORT_SYMBOL(ipa_wigig_conn_client); Loading @@ -1130,6 +1232,7 @@ int ipa_wigig_conn_client_smmu( struct ipa_wigig_conn_tx_in_params_smmu *in, struct ipa_wigig_conn_out_params *out) { char netdev_name[IPA_RESOURCE_NAME_MAX]; int ret; IPA_WIGIG_DBG("\n"); Loading @@ -1155,6 +1258,11 @@ int ipa_wigig_conn_client_smmu( return ret; } if (ipa_wigig_get_devname(netdev_name)) { IPA_WIGIG_ERR("couldn't get dev name\n"); return -EFAULT; } if (ipa_conn_wigig_client_i(in, out)) { IPA_WIGIG_ERR( "fail to connect client. MAC [%X][%X][%X][%X][%X][%X]\n" Loading @@ -1164,14 +1272,31 @@ int ipa_wigig_conn_client_smmu( return -EFAULT; } if (ipa_wigig_send_msg(WIGIG_CLIENT_CONNECT, netdev_name, in->client_mac, out->client, false)) { IPA_WIGIG_ERR("couldn't send msg to IPACM\n"); ret = -EFAULT; goto fail_sendmsg; } ret = ipa_wigig_store_client_smmu_info(in, out->client); if (ret) goto fail_smmu; ipa_wigig_store_client_mac(out->client, in->client_mac); IPA_WIGIG_DBG("exit\n"); return 0; fail_smmu: /* * wigig clients are disconnected with legacy message since there is * no need to send ep, client MAC is sufficient for disconnect */ ipa_wigig_send_wlan_msg(WLAN_CLIENT_DISCONNECT, netdev_name, in->client_mac); fail_sendmsg: ipa_disconn_wigig_pipe_i(out->client, &in->pipe_smmu, &in->dbuff_smmu); return ret; } Loading @@ -1197,6 +1322,8 @@ static inline int ipa_wigig_validate_client_type(enum ipa_client_type client) int ipa_wigig_disconn_pipe(enum ipa_client_type client) { int ret; char dev_name[IPA_RESOURCE_NAME_MAX]; char client_mac[IPA_MAC_ADDR_SIZE]; IPA_WIGIG_DBG("\n"); Loading @@ -1204,6 +1331,18 @@ int ipa_wigig_disconn_pipe(enum ipa_client_type client) if (ret) return ret; if (client != IPA_CLIENT_WIGIG_PROD) { if (ipa_wigig_get_devname(dev_name)) { IPA_WIGIG_ERR("couldn't get dev name\n"); return -EFAULT; } if (ipa_wigig_get_client_mac(client, client_mac)) { IPA_WIGIG_ERR("couldn't get client mac\n"); return -EFAULT; } } IPA_WIGIG_DBG("disconnecting ipa_client_type %d\n", client); if (ipa_wigig_is_smmu_enabled()) { Loading Loading @@ -1259,6 +1398,15 @@ int ipa_wigig_disconn_pipe(enum ipa_client_type client) IPA_WIGIG_ERR("failed dereg pm\n"); WARN_ON(1); } } else { /* * wigig clients are disconnected with legacy message since * there is no need to send ep, client MAC is sufficient for * disconnect. */ ipa_wigig_send_wlan_msg(WLAN_CLIENT_DISCONNECT, dev_name, client_mac); ipa_wigig_clean_client_mac(client); } if (ipa_wigig_is_smmu_enabled()) ipa_wigig_clean_smmu_info(client); Loading drivers/platform/msm/ipa/ipa_common_i.h +4 −0 Original line number Diff line number Diff line Loading @@ -462,4 +462,8 @@ int ipa_enable_wigig_pipe_i(enum ipa_client_type client); int ipa_disable_wigig_pipe_i(enum ipa_client_type client); int ipa_wigig_send_msg(int msg_type, const char *netdev_name, u8 *mac, enum ipa_client_type client, bool to_wigig); #endif /* _IPA_COMMON_I_H_ */ drivers/platform/msm/ipa/ipa_v3/ipa.c +14 −0 Original line number Diff line number Diff line Loading @@ -678,6 +678,7 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) struct ipa_ioc_rm_dependency rm_depend; struct ipa_ioc_nat_dma_cmd *table_dma_cmd; struct ipa_ioc_get_vlan_mode vlan_mode; struct ipa_ioc_wigig_fst_switch fst_switch; size_t sz; int pre_entry; Loading Loading @@ -1793,6 +1794,19 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) } break; case IPA_IOC_WIGIG_FST_SWITCH: IPADBG("Got IPA_IOCTL_WIGIG_FST_SWITCH\n"); if (copy_from_user(&fst_switch, (const void __user *)arg, sizeof(struct ipa_ioc_wigig_fst_switch))) { retval = -EFAULT; break; } retval = ipa_wigig_send_msg(WIGIG_FST_SWITCH, fst_switch.netdev_name, fst_switch.client_mac_addr, IPA_CLIENT_MAX, fst_switch.to_wigig); break; default: IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); return -ENOTTY; Loading include/uapi/linux/msm_ipa.h +38 −1 Original line number Diff line number Diff line Loading @@ -110,6 +110,7 @@ #define IPA_IOCTL_ODL_QUERY_MODEM_CONFIG 63 #define IPA_IOCTL_GSB_CONNECT 64 #define IPA_IOCTL_GSB_DISCONNECT 65 #define IPA_IOCTL_WIGIG_FST_SWITCH 66 /** Loading Loading @@ -612,7 +613,11 @@ enum ipa_coalesce_event { #define IPA_COALESCE_EVENT_MAX IPA_COALESCE_EVENT_MAX }; #define IPA_EVENT_MAX_NUM (IPA_COALESCE_EVENT_MAX) #define WIGIG_CLIENT_CONNECT (IPA_COALESCE_EVENT_MAX) #define WIGIG_FST_SWITCH (WIGIG_CLIENT_CONNECT + 1) #define WIGIG_EVENT_MAX (WIGIG_FST_SWITCH + 1) #define IPA_EVENT_MAX_NUM (WIGIG_EVENT_MAX) #define IPA_EVENT_MAX ((int)IPA_EVENT_MAX_NUM) /** Loading Loading @@ -1795,6 +1800,18 @@ struct ipa_ioc_gsb_info { char name[IPA_RESOURCE_NAME_MAX]; }; /** * struct ipa_ioc_wigig_fst_switch - switch between wigig and wlan * @netdev_name: wigig interface name * @client_mac_addr: client to switch between netdevs * @to_wigig: shall wlan client switch to wigig or the opposite? */ struct ipa_ioc_wigig_fst_switch { uint8_t netdev_name[IPA_RESOURCE_NAME_MAX]; uint8_t client_mac_addr[IPA_MAC_ADDR_SIZE]; int to_wigig; }; /** * struct ipa_msg_meta - Format of the message meta-data. * @msg_type: the type of the message Loading Loading @@ -1879,6 +1896,22 @@ struct ipa_wlan_msg_ex { struct ipa_wlan_hdr_attrib_val attribs[0]; }; /** * struct ipa_wigig_msg- To hold information about wigig event * @name: name of the wigig interface * @client_mac_addr: the relevant wigig client mac address * @ipa_client: TX pipe associated with the wigig client in case of connect * @to_wigig: FST switch direction wlan->wigig? */ struct ipa_wigig_msg { char name[IPA_RESOURCE_NAME_MAX]; uint8_t client_mac_addr[IPA_MAC_ADDR_SIZE]; union { enum ipa_client_type ipa_client; uint8_t to_wigig; } u; }; struct ipa_ecm_msg { char name[IPA_RESOURCE_NAME_MAX]; int ifindex; Loading Loading @@ -2251,6 +2284,10 @@ struct ipa_odl_modem_config { IPA_IOCTL_GSB_DISCONNECT, \ struct ipa_ioc_gsb_info) #define IPA_IOC_WIGIG_FST_SWITCH _IOWR(IPA_IOC_MAGIC, \ IPA_IOCTL_WIGIG_FST_SWITCH, \ struct ipa_ioc_wigig_fst_switch) /* * unique magic number of the Tethering bridge ioctls */ Loading Loading
drivers/platform/msm/ipa/ipa_clients/ipa_wigig.c +162 −14 Original line number Diff line number Diff line Loading @@ -62,6 +62,7 @@ struct ipa_wigig_context { struct ipa_wigig_rx_pipe_data_buffer_info_smmu rx_buff_smmu; struct ipa_wigig_tx_pipe_data_buffer_info_smmu tx_buff_smmu[IPA_WIGIG_TX_PIPE_NUM]; char clients_mac[IPA_WIGIG_TX_PIPE_NUM][IPA_MAC_ADDR_SIZE]; }; static struct ipa_wigig_context *ipa_wigig_ctx; Loading Loading @@ -216,35 +217,85 @@ static void ipa_wigig_free_msg(void *msg, uint32_t len, uint32_t type) IPA_WIGIG_DBG("exit\n"); } static int ipa_wigig_send_msg(uint8_t msg_type, const char *netdev_name, u8 *netdev_mac) static int ipa_wigig_send_wlan_msg(enum ipa_wlan_event msg_type, const char *netdev_name, u8 *mac) { struct ipa_msg_meta msg_meta; struct ipa_wlan_msg *msg; struct ipa_wlan_msg *wlan_msg; int ret; IPA_WIGIG_DBG("\n"); IPA_WIGIG_DBG("%d\n", msg_type); msg_meta.msg_type = msg_type; wlan_msg = kzalloc(sizeof(*wlan_msg), GFP_KERNEL); if (wlan_msg == NULL) return -ENOMEM; strlcpy(wlan_msg->name, netdev_name, IPA_RESOURCE_NAME_MAX); memcpy(wlan_msg->mac_addr, mac, IPA_MAC_ADDR_SIZE); msg_meta.msg_len = sizeof(struct ipa_wlan_msg); msg_meta.msg_type = msg_type; IPA_WIGIG_DBG("send msg type:%d, len:%d, buff %pK", msg_meta.msg_type, msg_meta.msg_len, wlan_msg); ret = ipa_send_msg(&msg_meta, wlan_msg, ipa_wigig_free_msg); IPA_WIGIG_DBG("exit\n"); return ret; } int ipa_wigig_send_msg(int msg_type, const char *netdev_name, u8 *mac, enum ipa_client_type client, bool to_wigig) { struct ipa_msg_meta msg_meta; struct ipa_wigig_msg *wigig_msg; int ret; msg = kzalloc(sizeof(*msg), GFP_KERNEL); if (msg == NULL) IPA_WIGIG_DBG("\n"); wigig_msg = kzalloc(sizeof(struct ipa_wigig_msg), GFP_KERNEL); if (wigig_msg == NULL) return -ENOMEM; strlcpy(wigig_msg->name, netdev_name, IPA_RESOURCE_NAME_MAX); memcpy(wigig_msg->client_mac_addr, mac, IPA_MAC_ADDR_SIZE); if (msg_type == WIGIG_CLIENT_CONNECT) wigig_msg->u.ipa_client = client; else wigig_msg->u.to_wigig = to_wigig; strlcpy(msg->name, netdev_name, IPA_RESOURCE_NAME_MAX); memcpy(msg->mac_addr, netdev_mac, IPA_MAC_ADDR_SIZE); msg_meta.msg_type = msg_type; msg_meta.msg_len = sizeof(struct ipa_wigig_msg); IPA_WIGIG_DBG("send msg type:%d, len:%d, buff %pK", msg_meta.msg_type, msg_meta.msg_len, msg); ret = ipa_send_msg(&msg_meta, msg, ipa_wigig_free_msg); msg_meta.msg_len, wigig_msg); ret = ipa_send_msg(&msg_meta, wigig_msg, ipa_wigig_free_msg); IPA_WIGIG_DBG("exit\n"); return ret; } static int ipa_wigig_get_devname(char *netdev_name) { struct ipa_wigig_intf_info *entry; mutex_lock(&ipa_wigig_ctx->lock); if (!list_is_singular(&ipa_wigig_ctx->head_intf_list)) { IPA_WIGIG_DBG("list is not singular, was an IF registered?\n"); mutex_unlock(&ipa_wigig_ctx->lock); return -EFAULT; } entry = list_first_entry(&ipa_wigig_ctx->head_intf_list, struct ipa_wigig_intf_info, link); strlcpy(netdev_name, entry->netdev_name, IPA_RESOURCE_NAME_MAX); mutex_unlock(&ipa_wigig_ctx->lock); return 0; } int ipa_wigig_reg_intf( struct ipa_wigig_reg_intf_in_params *in) { Loading Loading @@ -359,7 +410,7 @@ int ipa_wigig_reg_intf( goto fail_register; } if (ipa_wigig_send_msg(WLAN_AP_CONNECT, if (ipa_wigig_send_wlan_msg(WLAN_AP_CONNECT, in->netdev_name, in->netdev_mac)) { IPA_WIGIG_ERR("couldn't send msg to IPACM\n"); Loading Loading @@ -453,7 +504,7 @@ int ipa_wigig_dereg_intf(const char *netdev_name) goto fail; } if (ipa_wigig_send_msg(WLAN_AP_DISCONNECT, if (ipa_wigig_send_wlan_msg(WLAN_AP_DISCONNECT, entry->netdev_name, entry->netdev_mac)) { IPA_WIGIG_ERR("couldn't send msg to IPACM\n"); Loading Loading @@ -1088,9 +1139,43 @@ int ipa_wigig_set_perf_profile(u32 max_supported_bw_mbps) } EXPORT_SYMBOL(ipa_wigig_set_perf_profile); static int ipa_wigig_store_client_mac(enum ipa_client_type client, const char *mac) { unsigned int idx; if (ipa_wigig_client_to_idx(client, &idx)) { IPA_WIGIG_ERR("couldn't acquire idx\n"); return -EFAULT; } memcpy(ipa_wigig_ctx->clients_mac[idx - 1], mac, IPA_MAC_ADDR_SIZE); return 0; } static int ipa_wigig_get_client_mac(enum ipa_client_type client, char *mac) { unsigned int idx; if (ipa_wigig_client_to_idx(client, &idx)) { IPA_WIGIG_ERR("couldn't acquire idx\n"); return -EFAULT; } memcpy(mac, ipa_wigig_ctx->clients_mac[idx - 1], IPA_MAC_ADDR_SIZE); return 0; } static int ipa_wigig_clean_client_mac(enum ipa_client_type client) { char zero_mac[IPA_MAC_ADDR_SIZE] = { 0 }; return ipa_wigig_store_client_mac(client, zero_mac); } int ipa_wigig_conn_client(struct ipa_wigig_conn_tx_in_params *in, struct ipa_wigig_conn_out_params *out) { char dev_name[IPA_RESOURCE_NAME_MAX]; IPA_WIGIG_DBG("\n"); if (!in || !out) { Loading @@ -1113,6 +1198,11 @@ int ipa_wigig_conn_client(struct ipa_wigig_conn_tx_in_params *in, return -EFAULT; } if (ipa_wigig_get_devname(dev_name)) { IPA_WIGIG_ERR("couldn't get dev name\n"); return -EFAULT; } if (ipa_conn_wigig_client_i(in, out)) { IPA_WIGIG_ERR( "fail to connect client. MAC [%X][%X][%X][%X][%X][%X]\n" Loading @@ -1121,8 +1211,20 @@ int ipa_wigig_conn_client(struct ipa_wigig_conn_tx_in_params *in, return -EFAULT; } if (ipa_wigig_send_msg(WIGIG_CLIENT_CONNECT, dev_name, in->client_mac, out->client, false)) { IPA_WIGIG_ERR("couldn't send msg to IPACM\n"); goto fail_sendmsg; } ipa_wigig_store_client_mac(out->client, in->client_mac); IPA_WIGIG_DBG("exit\n"); return 0; fail_sendmsg: ipa_disconn_wigig_pipe_i(out->client, NULL, NULL); return -EFAULT; } EXPORT_SYMBOL(ipa_wigig_conn_client); Loading @@ -1130,6 +1232,7 @@ int ipa_wigig_conn_client_smmu( struct ipa_wigig_conn_tx_in_params_smmu *in, struct ipa_wigig_conn_out_params *out) { char netdev_name[IPA_RESOURCE_NAME_MAX]; int ret; IPA_WIGIG_DBG("\n"); Loading @@ -1155,6 +1258,11 @@ int ipa_wigig_conn_client_smmu( return ret; } if (ipa_wigig_get_devname(netdev_name)) { IPA_WIGIG_ERR("couldn't get dev name\n"); return -EFAULT; } if (ipa_conn_wigig_client_i(in, out)) { IPA_WIGIG_ERR( "fail to connect client. MAC [%X][%X][%X][%X][%X][%X]\n" Loading @@ -1164,14 +1272,31 @@ int ipa_wigig_conn_client_smmu( return -EFAULT; } if (ipa_wigig_send_msg(WIGIG_CLIENT_CONNECT, netdev_name, in->client_mac, out->client, false)) { IPA_WIGIG_ERR("couldn't send msg to IPACM\n"); ret = -EFAULT; goto fail_sendmsg; } ret = ipa_wigig_store_client_smmu_info(in, out->client); if (ret) goto fail_smmu; ipa_wigig_store_client_mac(out->client, in->client_mac); IPA_WIGIG_DBG("exit\n"); return 0; fail_smmu: /* * wigig clients are disconnected with legacy message since there is * no need to send ep, client MAC is sufficient for disconnect */ ipa_wigig_send_wlan_msg(WLAN_CLIENT_DISCONNECT, netdev_name, in->client_mac); fail_sendmsg: ipa_disconn_wigig_pipe_i(out->client, &in->pipe_smmu, &in->dbuff_smmu); return ret; } Loading @@ -1197,6 +1322,8 @@ static inline int ipa_wigig_validate_client_type(enum ipa_client_type client) int ipa_wigig_disconn_pipe(enum ipa_client_type client) { int ret; char dev_name[IPA_RESOURCE_NAME_MAX]; char client_mac[IPA_MAC_ADDR_SIZE]; IPA_WIGIG_DBG("\n"); Loading @@ -1204,6 +1331,18 @@ int ipa_wigig_disconn_pipe(enum ipa_client_type client) if (ret) return ret; if (client != IPA_CLIENT_WIGIG_PROD) { if (ipa_wigig_get_devname(dev_name)) { IPA_WIGIG_ERR("couldn't get dev name\n"); return -EFAULT; } if (ipa_wigig_get_client_mac(client, client_mac)) { IPA_WIGIG_ERR("couldn't get client mac\n"); return -EFAULT; } } IPA_WIGIG_DBG("disconnecting ipa_client_type %d\n", client); if (ipa_wigig_is_smmu_enabled()) { Loading Loading @@ -1259,6 +1398,15 @@ int ipa_wigig_disconn_pipe(enum ipa_client_type client) IPA_WIGIG_ERR("failed dereg pm\n"); WARN_ON(1); } } else { /* * wigig clients are disconnected with legacy message since * there is no need to send ep, client MAC is sufficient for * disconnect. */ ipa_wigig_send_wlan_msg(WLAN_CLIENT_DISCONNECT, dev_name, client_mac); ipa_wigig_clean_client_mac(client); } if (ipa_wigig_is_smmu_enabled()) ipa_wigig_clean_smmu_info(client); Loading
drivers/platform/msm/ipa/ipa_common_i.h +4 −0 Original line number Diff line number Diff line Loading @@ -462,4 +462,8 @@ int ipa_enable_wigig_pipe_i(enum ipa_client_type client); int ipa_disable_wigig_pipe_i(enum ipa_client_type client); int ipa_wigig_send_msg(int msg_type, const char *netdev_name, u8 *mac, enum ipa_client_type client, bool to_wigig); #endif /* _IPA_COMMON_I_H_ */
drivers/platform/msm/ipa/ipa_v3/ipa.c +14 −0 Original line number Diff line number Diff line Loading @@ -678,6 +678,7 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) struct ipa_ioc_rm_dependency rm_depend; struct ipa_ioc_nat_dma_cmd *table_dma_cmd; struct ipa_ioc_get_vlan_mode vlan_mode; struct ipa_ioc_wigig_fst_switch fst_switch; size_t sz; int pre_entry; Loading Loading @@ -1793,6 +1794,19 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) } break; case IPA_IOC_WIGIG_FST_SWITCH: IPADBG("Got IPA_IOCTL_WIGIG_FST_SWITCH\n"); if (copy_from_user(&fst_switch, (const void __user *)arg, sizeof(struct ipa_ioc_wigig_fst_switch))) { retval = -EFAULT; break; } retval = ipa_wigig_send_msg(WIGIG_FST_SWITCH, fst_switch.netdev_name, fst_switch.client_mac_addr, IPA_CLIENT_MAX, fst_switch.to_wigig); break; default: IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); return -ENOTTY; Loading
include/uapi/linux/msm_ipa.h +38 −1 Original line number Diff line number Diff line Loading @@ -110,6 +110,7 @@ #define IPA_IOCTL_ODL_QUERY_MODEM_CONFIG 63 #define IPA_IOCTL_GSB_CONNECT 64 #define IPA_IOCTL_GSB_DISCONNECT 65 #define IPA_IOCTL_WIGIG_FST_SWITCH 66 /** Loading Loading @@ -612,7 +613,11 @@ enum ipa_coalesce_event { #define IPA_COALESCE_EVENT_MAX IPA_COALESCE_EVENT_MAX }; #define IPA_EVENT_MAX_NUM (IPA_COALESCE_EVENT_MAX) #define WIGIG_CLIENT_CONNECT (IPA_COALESCE_EVENT_MAX) #define WIGIG_FST_SWITCH (WIGIG_CLIENT_CONNECT + 1) #define WIGIG_EVENT_MAX (WIGIG_FST_SWITCH + 1) #define IPA_EVENT_MAX_NUM (WIGIG_EVENT_MAX) #define IPA_EVENT_MAX ((int)IPA_EVENT_MAX_NUM) /** Loading Loading @@ -1795,6 +1800,18 @@ struct ipa_ioc_gsb_info { char name[IPA_RESOURCE_NAME_MAX]; }; /** * struct ipa_ioc_wigig_fst_switch - switch between wigig and wlan * @netdev_name: wigig interface name * @client_mac_addr: client to switch between netdevs * @to_wigig: shall wlan client switch to wigig or the opposite? */ struct ipa_ioc_wigig_fst_switch { uint8_t netdev_name[IPA_RESOURCE_NAME_MAX]; uint8_t client_mac_addr[IPA_MAC_ADDR_SIZE]; int to_wigig; }; /** * struct ipa_msg_meta - Format of the message meta-data. * @msg_type: the type of the message Loading Loading @@ -1879,6 +1896,22 @@ struct ipa_wlan_msg_ex { struct ipa_wlan_hdr_attrib_val attribs[0]; }; /** * struct ipa_wigig_msg- To hold information about wigig event * @name: name of the wigig interface * @client_mac_addr: the relevant wigig client mac address * @ipa_client: TX pipe associated with the wigig client in case of connect * @to_wigig: FST switch direction wlan->wigig? */ struct ipa_wigig_msg { char name[IPA_RESOURCE_NAME_MAX]; uint8_t client_mac_addr[IPA_MAC_ADDR_SIZE]; union { enum ipa_client_type ipa_client; uint8_t to_wigig; } u; }; struct ipa_ecm_msg { char name[IPA_RESOURCE_NAME_MAX]; int ifindex; Loading Loading @@ -2251,6 +2284,10 @@ struct ipa_odl_modem_config { IPA_IOCTL_GSB_DISCONNECT, \ struct ipa_ioc_gsb_info) #define IPA_IOC_WIGIG_FST_SWITCH _IOWR(IPA_IOC_MAGIC, \ IPA_IOCTL_WIGIG_FST_SWITCH, \ struct ipa_ioc_wigig_fst_switch) /* * unique magic number of the Tethering bridge ioctls */ Loading