Loading drivers/platform/msm/ipa/ipa_clients/ipa_usb.c +73 −0 Original line number Original line Diff line number Diff line Loading @@ -175,6 +175,23 @@ struct ipa3_usb_smmu_reg_map { phys_addr_t addr; phys_addr_t addr; }; }; /* * Relevant for IPA4.5 on sdx55v1 and Kona. */ static const bool teth_type_switch_tbl_ipa45 [IPA_USB_MAX_TETH_PROT_SIZE][IPA_USB_MAX_TETH_PROT_SIZE] = { [IPA_USB_RNDIS] = {true, false, false, false, false}, [IPA_USB_ECM] = {false, true, false, false, false}, [IPA_USB_RMNET] = {true, false, true, false, false}, [IPA_USB_MBIM] = {true, true, true, true, false}, [IPA_USB_DIAG] = {false, false, false, false, true}, }; struct ipa3_usb_teth_type_switch { bool valid; enum ipa_usb_teth_prot teth; }; struct ipa3_usb_context { struct ipa3_usb_context { struct ipa3_usb_teth_prot_context struct ipa3_usb_teth_prot_context teth_prot_ctx[IPA_USB_MAX_TETH_PROT_SIZE]; teth_prot_ctx[IPA_USB_MAX_TETH_PROT_SIZE]; Loading @@ -191,6 +208,7 @@ struct ipa3_usb_context { struct dentry *dfile_state_info; struct dentry *dfile_state_info; struct dentry *dent; struct dentry *dent; struct ipa3_usb_smmu_reg_map smmu_reg_map; struct ipa3_usb_smmu_reg_map smmu_reg_map; struct ipa3_usb_teth_type_switch prev_teth; }; }; enum ipa3_usb_op { enum ipa3_usb_op { Loading Loading @@ -861,6 +879,56 @@ static int ipa3_usb_create_rm_resources(enum ipa3_usb_transport_type ttype) return result; return result; } } static bool ipa3_usb_is_teth_switch_valid(enum ipa_usb_teth_prot new_teth) { enum ipa_usb_teth_prot old_teth; u32 ipa_r_rev; IPA_USB_DBG("Start new_teth=%s\n", ipa3_usb_teth_prot_to_string(new_teth)); if (IPA3_USB_IS_TTYPE_DPL(IPA3_USB_GET_TTYPE(new_teth))) return true; if (ipa3_ctx->ipa_hw_type != IPA_HW_v4_5) return true; ipa_r_rev = ipa3_get_r_rev_version(); IPA_USB_DBG("ipa_r_rev=%u\n", ipa_r_rev); /* issue relevant for IPA4.5v1 */ if (ipa_r_rev != 10 && ipa_r_rev != 13) return true; if (ipa3_usb_ctx == NULL) { IPA_USB_ERR("Invalid context"); return false; } if (new_teth < 0 || new_teth >= IPA_USB_MAX_TETH_PROT_SIZE) { IPA_USB_ERR("Invalid new_teth %d\n", new_teth); return false; } if (!ipa3_usb_ctx->prev_teth.valid) { ipa3_usb_ctx->prev_teth.teth = new_teth; ipa3_usb_ctx->prev_teth.valid = true; return true; } old_teth = ipa3_usb_ctx->prev_teth.teth; if (teth_type_switch_tbl_ipa45[old_teth][new_teth]) { ipa3_usb_ctx->prev_teth.teth = new_teth; return true; } IPA_USB_DBG("Invalid teth switch %s -> %s\n", ipa3_usb_teth_prot_to_string(old_teth), ipa3_usb_teth_prot_to_string(new_teth)); return false; } int ipa_usb_init_teth_prot(enum ipa_usb_teth_prot teth_prot, int ipa_usb_init_teth_prot(enum ipa_usb_teth_prot teth_prot, struct ipa_usb_teth_params *teth_params, struct ipa_usb_teth_params *teth_params, int (*ipa_usb_notify_cb)(enum ipa_usb_notify_event, int (*ipa_usb_notify_cb)(enum ipa_usb_notify_event, Loading Loading @@ -2192,6 +2260,11 @@ int ipa_usb_xdci_connect(struct ipa_usb_xdci_chan_params *ul_chan_params, goto bad_params; goto bad_params; } } if (!ipa3_usb_is_teth_switch_valid(connect_params->teth_prot)) { IPA_USB_ERR("Invalid teth type switch\n"); goto bad_params; } if (connect_params->teth_prot != IPA_USB_DIAG) { if (connect_params->teth_prot != IPA_USB_DIAG) { result = ipa3_usb_request_xdci_channel(ul_chan_params, result = ipa3_usb_request_xdci_channel(ul_chan_params, IPA_USB_DIR_UL, ul_out_params); IPA_USB_DIR_UL, ul_out_params); Loading drivers/platform/msm/ipa/ipa_v3/ipa_i.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -2735,6 +2735,7 @@ int ipa3_get_transport_info( unsigned long *size_ptr); unsigned long *size_ptr); irq_handler_t ipa3_get_isr(void); irq_handler_t ipa3_get_isr(void); void ipa_pc_qmp_enable(void); void ipa_pc_qmp_enable(void); u32 ipa3_get_r_rev_version(void); #if defined(CONFIG_IPA3_REGDUMP) #if defined(CONFIG_IPA3_REGDUMP) int ipa_reg_save_init(u32 value); int ipa_reg_save_init(u32 value); void ipa_save_registers(void); void ipa_save_registers(void); Loading drivers/platform/msm/ipa/ipa_v3/ipa_utils.c +14 −0 Original line number Original line Diff line number Diff line Loading @@ -8120,3 +8120,17 @@ void ipa3_init_imm_cmd_desc(struct ipa3_desc *desc, desc->len = cmd_pyld->len; desc->len = cmd_pyld->len; desc->type = IPA_IMM_CMD_DESC; desc->type = IPA_IMM_CMD_DESC; } } u32 ipa3_get_r_rev_version(void) { static u32 r_rev; if (r_rev != 0) return r_rev; IPA_ACTIVE_CLIENTS_INC_SIMPLE(); r_rev = ipahal_read_reg(IPA_VERSION); IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); return r_rev; } Loading
drivers/platform/msm/ipa/ipa_clients/ipa_usb.c +73 −0 Original line number Original line Diff line number Diff line Loading @@ -175,6 +175,23 @@ struct ipa3_usb_smmu_reg_map { phys_addr_t addr; phys_addr_t addr; }; }; /* * Relevant for IPA4.5 on sdx55v1 and Kona. */ static const bool teth_type_switch_tbl_ipa45 [IPA_USB_MAX_TETH_PROT_SIZE][IPA_USB_MAX_TETH_PROT_SIZE] = { [IPA_USB_RNDIS] = {true, false, false, false, false}, [IPA_USB_ECM] = {false, true, false, false, false}, [IPA_USB_RMNET] = {true, false, true, false, false}, [IPA_USB_MBIM] = {true, true, true, true, false}, [IPA_USB_DIAG] = {false, false, false, false, true}, }; struct ipa3_usb_teth_type_switch { bool valid; enum ipa_usb_teth_prot teth; }; struct ipa3_usb_context { struct ipa3_usb_context { struct ipa3_usb_teth_prot_context struct ipa3_usb_teth_prot_context teth_prot_ctx[IPA_USB_MAX_TETH_PROT_SIZE]; teth_prot_ctx[IPA_USB_MAX_TETH_PROT_SIZE]; Loading @@ -191,6 +208,7 @@ struct ipa3_usb_context { struct dentry *dfile_state_info; struct dentry *dfile_state_info; struct dentry *dent; struct dentry *dent; struct ipa3_usb_smmu_reg_map smmu_reg_map; struct ipa3_usb_smmu_reg_map smmu_reg_map; struct ipa3_usb_teth_type_switch prev_teth; }; }; enum ipa3_usb_op { enum ipa3_usb_op { Loading Loading @@ -861,6 +879,56 @@ static int ipa3_usb_create_rm_resources(enum ipa3_usb_transport_type ttype) return result; return result; } } static bool ipa3_usb_is_teth_switch_valid(enum ipa_usb_teth_prot new_teth) { enum ipa_usb_teth_prot old_teth; u32 ipa_r_rev; IPA_USB_DBG("Start new_teth=%s\n", ipa3_usb_teth_prot_to_string(new_teth)); if (IPA3_USB_IS_TTYPE_DPL(IPA3_USB_GET_TTYPE(new_teth))) return true; if (ipa3_ctx->ipa_hw_type != IPA_HW_v4_5) return true; ipa_r_rev = ipa3_get_r_rev_version(); IPA_USB_DBG("ipa_r_rev=%u\n", ipa_r_rev); /* issue relevant for IPA4.5v1 */ if (ipa_r_rev != 10 && ipa_r_rev != 13) return true; if (ipa3_usb_ctx == NULL) { IPA_USB_ERR("Invalid context"); return false; } if (new_teth < 0 || new_teth >= IPA_USB_MAX_TETH_PROT_SIZE) { IPA_USB_ERR("Invalid new_teth %d\n", new_teth); return false; } if (!ipa3_usb_ctx->prev_teth.valid) { ipa3_usb_ctx->prev_teth.teth = new_teth; ipa3_usb_ctx->prev_teth.valid = true; return true; } old_teth = ipa3_usb_ctx->prev_teth.teth; if (teth_type_switch_tbl_ipa45[old_teth][new_teth]) { ipa3_usb_ctx->prev_teth.teth = new_teth; return true; } IPA_USB_DBG("Invalid teth switch %s -> %s\n", ipa3_usb_teth_prot_to_string(old_teth), ipa3_usb_teth_prot_to_string(new_teth)); return false; } int ipa_usb_init_teth_prot(enum ipa_usb_teth_prot teth_prot, int ipa_usb_init_teth_prot(enum ipa_usb_teth_prot teth_prot, struct ipa_usb_teth_params *teth_params, struct ipa_usb_teth_params *teth_params, int (*ipa_usb_notify_cb)(enum ipa_usb_notify_event, int (*ipa_usb_notify_cb)(enum ipa_usb_notify_event, Loading Loading @@ -2192,6 +2260,11 @@ int ipa_usb_xdci_connect(struct ipa_usb_xdci_chan_params *ul_chan_params, goto bad_params; goto bad_params; } } if (!ipa3_usb_is_teth_switch_valid(connect_params->teth_prot)) { IPA_USB_ERR("Invalid teth type switch\n"); goto bad_params; } if (connect_params->teth_prot != IPA_USB_DIAG) { if (connect_params->teth_prot != IPA_USB_DIAG) { result = ipa3_usb_request_xdci_channel(ul_chan_params, result = ipa3_usb_request_xdci_channel(ul_chan_params, IPA_USB_DIR_UL, ul_out_params); IPA_USB_DIR_UL, ul_out_params); Loading
drivers/platform/msm/ipa/ipa_v3/ipa_i.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -2735,6 +2735,7 @@ int ipa3_get_transport_info( unsigned long *size_ptr); unsigned long *size_ptr); irq_handler_t ipa3_get_isr(void); irq_handler_t ipa3_get_isr(void); void ipa_pc_qmp_enable(void); void ipa_pc_qmp_enable(void); u32 ipa3_get_r_rev_version(void); #if defined(CONFIG_IPA3_REGDUMP) #if defined(CONFIG_IPA3_REGDUMP) int ipa_reg_save_init(u32 value); int ipa_reg_save_init(u32 value); void ipa_save_registers(void); void ipa_save_registers(void); Loading
drivers/platform/msm/ipa/ipa_v3/ipa_utils.c +14 −0 Original line number Original line Diff line number Diff line Loading @@ -8120,3 +8120,17 @@ void ipa3_init_imm_cmd_desc(struct ipa3_desc *desc, desc->len = cmd_pyld->len; desc->len = cmd_pyld->len; desc->type = IPA_IMM_CMD_DESC; desc->type = IPA_IMM_CMD_DESC; } } u32 ipa3_get_r_rev_version(void) { static u32 r_rev; if (r_rev != 0) return r_rev; IPA_ACTIVE_CLIENTS_INC_SIMPLE(); r_rev = ipahal_read_reg(IPA_VERSION); IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); return r_rev; }