port_kernel.c 117 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360
  1. #include <linux/device.h>
  2. #include <linux/wait.h>
  3. #include <linux/module.h>
  4. #include <linux/sched.h>
  5. #include <linux/kthread.h>
  6. #include <linux/rtc.h>
  7. #include <linux/kernel.h>
  8. #include <mt-plat/mt_boot_common.h>
  9. #include <linux/fs.h>
  10. #include <linux/random.h>
  11. #include <linux/timer.h>
  12. #include <linux/of.h>
  13. #include <linux/of_fdt.h>
  14. #include <linux/of_irq.h>
  15. #include <linux/of_address.h>
  16. #include "ccci_config.h"
  17. #ifdef FEATURE_GET_MD_EINT_ATTR_DTS
  18. #include <linux/irq.h>
  19. #endif
  20. #ifdef ENABLE_MD_IMG_SECURITY_FEATURE
  21. #include <sec_export.h>
  22. #endif
  23. #if defined(CONFIG_MTK_AEE_FEATURE)
  24. #include <mt-plat/aee.h>
  25. #else
  26. #define DB_OPT_DEFAULT (0) /* Dummy macro define to avoid build error */
  27. #define DB_OPT_FTRACE (0) /* Dummy macro define to avoid build error */
  28. #endif
  29. #ifdef FEATURE_INFORM_NFC_VSIM_CHANGE
  30. #include <mach/mt6605.h>
  31. #endif
  32. #include <mt-plat/mt_gpio.h>
  33. #include <mt-plat/mt_gpio_core.h>
  34. #ifdef FEATURE_RF_CLK_BUF
  35. #include <linux/gpio.h>
  36. #include <mt_clkbuf_ctl.h>
  37. #endif
  38. #ifdef FEATURE_GET_MD_GPIO_VAL
  39. #include <linux/gpio.h>
  40. #endif
  41. #include "ccci_core.h"
  42. #include "ccci_bm.h"
  43. #include "ccci_platform.h"
  44. #include "port_kernel.h"
  45. #if defined(ENABLE_32K_CLK_LESS)
  46. #include <mt-plat/mtk_rtc.h>
  47. #endif
  48. static void ccci_ee_info_dump(struct ccci_modem *md);
  49. static void ccci_aed(struct ccci_modem *md, unsigned int dump_flag, char *aed_str, int db_opt);
  50. static void status_msg_handler(struct ccci_port *port, struct ccci_request *req);
  51. #define MAX_QUEUE_LENGTH 16
  52. #define EX_TIMER_SWINT 10
  53. #define EX_TIMER_MD_EX 5
  54. #define EX_TIMER_MD_EX_REC_OK 30
  55. #define EX_TIMER_MD_HANG 5
  56. #if defined(FEATURE_GET_MD_GPIO_NUM)
  57. static struct gpio_item gpio_mapping_table[] = {
  58. {"GPIO_FDD_Band_Support_Detection_1", "GPIO_FDD_BAND_SUPPORT_DETECT_1ST_PIN",},
  59. {"GPIO_FDD_Band_Support_Detection_2", "GPIO_FDD_BAND_SUPPORT_DETECT_2ND_PIN",},
  60. {"GPIO_FDD_Band_Support_Detection_3", "GPIO_FDD_BAND_SUPPORT_DETECT_3RD_PIN",},
  61. {"GPIO_FDD_Band_Support_Detection_4", "GPIO_FDD_BAND_SUPPORT_DETECT_4TH_PIN",},
  62. {"GPIO_FDD_Band_Support_Detection_5", "GPIO_FDD_BAND_SUPPORT_DETECT_5TH_PIN",},
  63. {"GPIO_FDD_Band_Support_Detection_6", "GPIO_FDD_BAND_SUPPORT_DETECT_6TH_PIN",},
  64. {"GPIO_FDD_Band_Support_Detection_7", "GPIO_FDD_BAND_SUPPORT_DETECT_7TH_PIN",},
  65. {"GPIO_FDD_Band_Support_Detection_8", "GPIO_FDD_BAND_SUPPORT_DETECT_8TH_PIN",},
  66. {"GPIO_FDD_Band_Support_Detection_9", "GPIO_FDD_BAND_SUPPORT_DETECT_9TH_PIN",},
  67. {"GPIO_FDD_Band_Support_Detection_A", "GPIO_FDD_BAND_SUPPORT_DETECT_ATH_PIN",},
  68. };
  69. #endif
  70. #ifdef CONFIG_MTK_ECCCI_C2K
  71. int modem_dtr_set(int on, int low_latency)
  72. {
  73. struct ccci_modem *md = NULL;
  74. struct c2k_ctrl_port_msg c2k_ctl_msg;
  75. int ret = 0;
  76. /* only md3 can usb bypass */
  77. md = ccci_get_modem_by_id(MD_SYS3);
  78. c2k_ctl_msg.chan_num = DATA_PPP_CH_C2K;
  79. c2k_ctl_msg.id_hi = (C2K_STATUS_IND_MSG & 0xFF00) >> 8;
  80. c2k_ctl_msg.id_low = C2K_STATUS_IND_MSG & 0xFF;
  81. c2k_ctl_msg.option = 0;
  82. if (on)
  83. c2k_ctl_msg.option |= 0x04;
  84. else
  85. c2k_ctl_msg.option &= 0xFB;
  86. CCCI_INF_MSG(md->index, KERN, "usb bypass dtr set(%d)(0x%x)\n", on, (u32) (*((u32 *)&c2k_ctl_msg)));
  87. ccci_send_msg_to_md(md, CCCI_CONTROL_TX, C2K_STATUS_IND_MSG, (u32) (*((u32 *)&c2k_ctl_msg)), 1);
  88. return ret;
  89. }
  90. int modem_dcd_state(void)
  91. {
  92. struct ccci_modem *md = NULL;
  93. struct c2k_ctrl_port_msg c2k_ctl_msg;
  94. int dcd_state = 0;
  95. int ret = 0;
  96. /* only md3 can usb bypass */
  97. md = ccci_get_modem_by_id(MD_SYS3);
  98. c2k_ctl_msg.chan_num = DATA_PPP_CH_C2K;
  99. c2k_ctl_msg.id_hi = (C2K_STATUS_QUERY_MSG & 0xFF00) >> 8;
  100. c2k_ctl_msg.id_low = C2K_STATUS_QUERY_MSG & 0xFF;
  101. c2k_ctl_msg.option = 0;
  102. CCCI_INF_MSG(md->index, KERN, "usb bypass query state(0x%x)\n", (u32) (*((u32 *)&c2k_ctl_msg)));
  103. ret = ccci_send_msg_to_md(md, CCCI_CONTROL_TX, C2K_STATUS_QUERY_MSG, (u32) (*((u32 *)&c2k_ctl_msg)), 1);
  104. if (ret == -CCCI_ERR_MD_NOT_READY)
  105. dcd_state = 0;
  106. else {
  107. msleep(20);
  108. dcd_state = md->dtr_state;
  109. }
  110. return dcd_state;
  111. }
  112. #endif
  113. static inline void append_runtime_feature(char **p_rt_data, struct ccci_runtime_feature *rt_feature, void *data)
  114. {
  115. CCCI_DBG_MSG(-1, KERN, "append rt_data %p, feature %u len %u\n",
  116. *p_rt_data, rt_feature->feature_id, rt_feature->data_len);
  117. memcpy(*p_rt_data, rt_feature, sizeof(struct ccci_runtime_feature));
  118. *p_rt_data += sizeof(struct ccci_runtime_feature);
  119. if (data != NULL) {
  120. memcpy(*p_rt_data, data, rt_feature->data_len);
  121. *p_rt_data += rt_feature->data_len;
  122. }
  123. }
  124. static unsigned int get_booting_start_id(struct ccci_modem *md)
  125. {
  126. struct file *filp = NULL;
  127. LOGGING_MODE mdlog_flag = MODE_IDLE;
  128. char md_logger_cfg_file[32];
  129. u32 booting_start_id;
  130. int ret;
  131. if (md->index == 0)
  132. snprintf(md_logger_cfg_file, 32, "%s", MD1_LOGGER_FILE_PATH);
  133. else
  134. snprintf(md_logger_cfg_file, 32, "%s", MD2_LOGGER_FILE_PATH);
  135. CCCI_INF_MSG(md->index, KERN, "md_logger_cfg_file %s\n", md_logger_cfg_file);
  136. filp = filp_open(md_logger_cfg_file, O_RDONLY, 0777);
  137. if (!IS_ERR(filp)) {
  138. ret = kernel_read(filp, 0, (char *)&mdlog_flag, sizeof(int));
  139. if (ret != sizeof(int))
  140. mdlog_flag = MODE_IDLE;
  141. } else {
  142. CCCI_ERR_MSG(md->index, KERN, "open %s fail", md_logger_cfg_file);
  143. filp = NULL;
  144. }
  145. if (filp != NULL)
  146. filp_close(filp, NULL);
  147. if (is_meta_mode() || is_advanced_meta_mode())
  148. booting_start_id = ((char)mdlog_flag << 8 | META_BOOT_ID);
  149. else
  150. booting_start_id = ((char)mdlog_flag << 8 | NORMAL_BOOT_ID);
  151. return booting_start_id;
  152. }
  153. static void config_ap_side_feature(struct ccci_modem *md, struct md_query_ap_feature *ap_side_md_feature)
  154. {
  155. md->runtime_version = AP_MD_HS_V2;
  156. ap_side_md_feature->feature_set[BOOT_INFO].support_mask = CCCI_FEATURE_MUST_SUPPORT;
  157. ap_side_md_feature->feature_set[EXCEPTION_SHARE_MEMORY].support_mask = CCCI_FEATURE_MUST_SUPPORT;
  158. if (md->index == MD_SYS1)
  159. ap_side_md_feature->feature_set[CCIF_SHARE_MEMORY].support_mask = CCCI_FEATURE_NOT_SUPPORT;
  160. else
  161. ap_side_md_feature->feature_set[CCIF_SHARE_MEMORY].support_mask = CCCI_FEATURE_MUST_SUPPORT;
  162. #ifdef FEATURE_DHL_LOG_EN
  163. /*to do: enable DHL */
  164. ap_side_md_feature->feature_set[DHL_SHARE_MEMORY].support_mask = CCCI_FEATURE_NOT_SUPPORT;
  165. #else
  166. ap_side_md_feature->feature_set[DHL_SHARE_MEMORY].support_mask = CCCI_FEATURE_NOT_SUPPORT;
  167. #endif
  168. #ifdef FEATURE_MD1MD3_SHARE_MEM
  169. ap_side_md_feature->feature_set[MD1MD3_SHARE_MEMORY].support_mask = CCCI_FEATURE_MUST_SUPPORT;
  170. #else
  171. ap_side_md_feature->feature_set[MD1MD3_SHARE_MEMORY].support_mask = CCCI_FEATURE_NOT_SUPPORT;
  172. #endif
  173. ap_side_md_feature->feature_set[MISC_INFO_HIF_DMA_REMAP].support_mask = CCCI_FEATURE_MUST_SUPPORT;
  174. #if defined(ENABLE_32K_CLK_LESS)
  175. if (crystal_exist_status()) {
  176. CCCI_DBG_MSG(md->index, KERN, "MISC_32K_LESS no support, crystal_exist_status 1\n");
  177. ap_side_md_feature->feature_set[MISC_INFO_RTC_32K_LESS].support_mask = CCCI_FEATURE_NOT_SUPPORT;
  178. } else {
  179. CCCI_DBG_MSG(md->index, KERN, "MISC_32K_LESS support\n");
  180. ap_side_md_feature->feature_set[MISC_INFO_RTC_32K_LESS].support_mask = CCCI_FEATURE_MUST_SUPPORT;
  181. }
  182. #else
  183. CCCI_DBG_MSG(md->index, KERN, "ENABLE_32K_CLK_LESS disabled\n");
  184. ap_side_md_feature->feature_set[MISC_INFO_RTC_32K_LESS].support_mask = CCCI_FEATURE_NOT_SUPPORT;
  185. #endif
  186. ap_side_md_feature->feature_set[MISC_INFO_RANDOM_SEED_NUM].support_mask = CCCI_FEATURE_MUST_SUPPORT;
  187. ap_side_md_feature->feature_set[MISC_INFO_GPS_COCLOCK].support_mask = CCCI_FEATURE_MUST_SUPPORT;
  188. ap_side_md_feature->feature_set[MISC_INFO_SBP_ID].support_mask = CCCI_FEATURE_MUST_SUPPORT;
  189. ap_side_md_feature->feature_set[MISC_INFO_CCCI].support_mask = CCCI_FEATURE_MUST_SUPPORT;
  190. #ifdef FEATURE_MD_GET_CLIB_TIME
  191. ap_side_md_feature->feature_set[MISC_INFO_CLIB_TIME].support_mask = CCCI_FEATURE_MUST_SUPPORT;
  192. #else
  193. ap_side_md_feature->feature_set[MISC_INFO_CLIB_TIME].support_mask = CCCI_FEATURE_NOT_SUPPORT;
  194. #endif
  195. #ifdef FEATURE_C2K_ALWAYS_ON
  196. ap_side_md_feature->feature_set[MISC_INFO_C2K].support_mask = CCCI_FEATURE_MUST_SUPPORT;
  197. #else
  198. ap_side_md_feature->feature_set[MISC_INFO_C2K].support_mask = CCCI_FEATURE_NOT_SUPPORT;
  199. #endif
  200. }
  201. static int prepare_runtime_data(struct ccci_modem *md, struct ccci_request *req)
  202. {
  203. u8 i = 0;
  204. u32 total_len;
  205. /*runtime data buffer */
  206. char *rt_data = (char *)md->smem_layout.ccci_rt_smem_base_vir;
  207. struct ccci_runtime_feature rt_feature;
  208. /*runtime feature type */
  209. struct ccci_runtime_share_memory rt_shm;
  210. struct ccci_misc_info_element rt_f_element;
  211. struct md_query_ap_feature *md_feature;
  212. struct md_query_ap_feature md_feature_ap;
  213. struct ccci_runtime_boot_info boot_info;
  214. unsigned int random_seed = 0;
  215. struct timeval t;
  216. CCCI_NOTICE_MSG(md->index, KERN, "prepare_runtime_data rt_data %p\n", rt_data);
  217. memset(&md_feature_ap, 0, sizeof(struct md_query_ap_feature));
  218. config_ap_side_feature(md, &md_feature_ap);
  219. md_feature = (struct md_query_ap_feature *)skb_pull(req->skb, sizeof(struct ccci_header));
  220. if (md_feature->head_pattern != MD_FEATURE_QUERY_PATTERN ||
  221. md_feature->tail_pattern != MD_FEATURE_QUERY_PATTERN) {
  222. CCCI_ERR_MSG(md->index, KERN, "md_feature pattern is wrong: head 0x%x, tail 0x%x\n",
  223. md_feature->head_pattern, md_feature->tail_pattern);
  224. if (md->index == MD_SYS3)
  225. md->ops->dump_info(md, DUMP_FLAG_CCIF, NULL, 0);
  226. return -1;
  227. }
  228. for (i = BOOT_INFO; i < FEATURE_COUNT; i++) {
  229. memset(&rt_feature, 0, sizeof(struct ccci_runtime_feature));
  230. memset(&rt_shm, 0, sizeof(struct ccci_runtime_share_memory));
  231. memset(&rt_f_element, 0, sizeof(struct ccci_misc_info_element));
  232. rt_feature.feature_id = i;
  233. if (md_feature->feature_set[i].support_mask == CCCI_FEATURE_MUST_SUPPORT &&
  234. md_feature_ap.feature_set[i].support_mask < CCCI_FEATURE_MUST_SUPPORT) {
  235. CCCI_ERR_MSG(md->index, KERN, "feature %u not support for AP\n", rt_feature.feature_id);
  236. return -1;
  237. }
  238. CCCI_DBG_MSG(md->index, KERN, "md_query_ap_feature %u mask %u, version %u\n",
  239. rt_feature.feature_id, md_feature->feature_set[i].support_mask,
  240. md_feature->feature_set[i].version);
  241. if (md_feature->feature_set[i].support_mask == CCCI_FEATURE_NOT_EXIST) {
  242. rt_feature.support_info = md_feature->feature_set[i];
  243. } else if (md_feature->feature_set[i].support_mask == CCCI_FEATURE_MUST_SUPPORT) {
  244. rt_feature.support_info = md_feature->feature_set[i];
  245. } else if (md_feature->feature_set[i].support_mask == CCCI_FEATURE_OPTIONAL_SUPPORT) {
  246. if (md_feature->feature_set[i].version == md_feature_ap.feature_set[i].version &&
  247. md_feature_ap.feature_set[i].support_mask >= CCCI_FEATURE_MUST_SUPPORT) {
  248. rt_feature.support_info.support_mask = CCCI_FEATURE_MUST_SUPPORT;
  249. rt_feature.support_info.version = md_feature_ap.feature_set[i].version;
  250. } else {
  251. rt_feature.support_info.support_mask = CCCI_FEATURE_NOT_SUPPORT;
  252. rt_feature.support_info.version = md_feature_ap.feature_set[i].version;
  253. }
  254. } else if (md_feature->feature_set[i].support_mask == CCCI_FEATURE_SUPPORT_BACKWARD_COMPAT) {
  255. if (md_feature->feature_set[i].version >= md_feature_ap.feature_set[i].version) {
  256. rt_feature.support_info.support_mask = CCCI_FEATURE_MUST_SUPPORT;
  257. rt_feature.support_info.version = md_feature_ap.feature_set[i].version;
  258. } else {
  259. rt_feature.support_info.support_mask = CCCI_FEATURE_NOT_SUPPORT;
  260. rt_feature.support_info.version = md_feature_ap.feature_set[i].version;
  261. }
  262. }
  263. if (rt_feature.support_info.support_mask == CCCI_FEATURE_MUST_SUPPORT) {
  264. switch (rt_feature.feature_id) {
  265. case BOOT_INFO:
  266. memset(&boot_info, 0, sizeof(boot_info));
  267. rt_feature.data_len = sizeof(boot_info);
  268. boot_info.boot_channel = CCCI_CONTROL_RX;
  269. boot_info.booting_start_id = get_booting_start_id(md);
  270. append_runtime_feature(&rt_data, &rt_feature, &boot_info);
  271. break;
  272. case EXCEPTION_SHARE_MEMORY:
  273. rt_feature.data_len = sizeof(struct ccci_runtime_share_memory);
  274. rt_shm.addr = md->smem_layout.ccci_exp_smem_base_phy -
  275. md->mem_layout.smem_offset_AP_to_MD;
  276. rt_shm.size = md->smem_layout.ccci_exp_smem_size;
  277. append_runtime_feature(&rt_data, &rt_feature, &rt_shm);
  278. break;
  279. case CCIF_SHARE_MEMORY:
  280. rt_feature.data_len = sizeof(struct ccci_runtime_share_memory);
  281. rt_shm.addr = md->smem_layout.ccci_exp_smem_base_phy +
  282. md->smem_layout.ccci_exp_smem_size +
  283. md->smem_layout.ccci_rt_smem_size - md->mem_layout.smem_offset_AP_to_MD;
  284. rt_shm.size = md->smem_layout.ccci_ccif_smem_size;
  285. append_runtime_feature(&rt_data, &rt_feature, &rt_shm);
  286. break;
  287. case DHL_SHARE_MEMORY:
  288. rt_feature.data_len = sizeof(struct ccci_runtime_share_memory);
  289. rt_shm.addr = md->mem_layout.dhl_smem_phy - md->mem_layout.smem_offset_AP_to_MD;
  290. rt_shm.size = md->mem_layout.dhl_smem_size;
  291. append_runtime_feature(&rt_data, &rt_feature, &rt_shm);
  292. break;
  293. case MD1MD3_SHARE_MEMORY:
  294. rt_feature.data_len = sizeof(struct ccci_runtime_share_memory);
  295. rt_shm.addr = md->mem_layout.md1_md3_smem_phy - md->mem_layout.smem_offset_AP_to_MD;
  296. rt_shm.size = md->mem_layout.md1_md3_smem_size;
  297. append_runtime_feature(&rt_data, &rt_feature, &rt_shm);
  298. break;
  299. case MISC_INFO_HIF_DMA_REMAP:
  300. rt_feature.data_len = sizeof(struct ccci_misc_info_element);
  301. append_runtime_feature(&rt_data, &rt_feature, &rt_f_element);
  302. break;
  303. case MISC_INFO_RTC_32K_LESS:
  304. rt_feature.data_len = sizeof(struct ccci_misc_info_element);
  305. append_runtime_feature(&rt_data, &rt_feature, &rt_f_element);
  306. break;
  307. case MISC_INFO_RANDOM_SEED_NUM:
  308. rt_feature.data_len = sizeof(struct ccci_misc_info_element);
  309. get_random_bytes(&random_seed, sizeof(int));
  310. rt_f_element.feature[0] = random_seed;
  311. append_runtime_feature(&rt_data, &rt_feature, &rt_f_element);
  312. break;
  313. case MISC_INFO_GPS_COCLOCK:
  314. rt_feature.data_len = sizeof(struct ccci_misc_info_element);
  315. append_runtime_feature(&rt_data, &rt_feature, &rt_f_element);
  316. break;
  317. case MISC_INFO_SBP_ID:
  318. rt_feature.data_len = sizeof(struct ccci_misc_info_element);
  319. rt_f_element.feature[0] = md->sbp_code;
  320. if (md->config.load_type < modem_ultg)
  321. rt_f_element.feature[1] = 0;
  322. else
  323. rt_f_element.feature[1] = get_md_wm_id_map(md->config.load_type);
  324. append_runtime_feature(&rt_data, &rt_feature, &rt_f_element);
  325. break;
  326. case MISC_INFO_CCCI:
  327. rt_feature.data_len = sizeof(struct ccci_misc_info_element);
  328. #ifdef FEATURE_SEQ_CHECK_EN
  329. rt_f_element.feature[0] |= (1 << 0);
  330. #endif
  331. #ifdef FEATURE_POLL_MD_EN
  332. rt_f_element.feature[0] |= (1 << 1);
  333. #endif
  334. append_runtime_feature(&rt_data, &rt_feature, &rt_f_element);
  335. break;
  336. case MISC_INFO_CLIB_TIME:
  337. rt_feature.data_len = sizeof(struct ccci_misc_info_element);
  338. do_gettimeofday(&t);
  339. /*set seconds information */
  340. rt_f_element.feature[0] = ((unsigned int *)&t.tv_sec)[0];
  341. rt_f_element.feature[1] = ((unsigned int *)&t.tv_sec)[1];
  342. /*sys_tz.tz_minuteswest; */
  343. rt_f_element.feature[2] = current_time_zone;
  344. /*not used for now */
  345. rt_f_element.feature[3] = sys_tz.tz_dsttime;
  346. append_runtime_feature(&rt_data, &rt_feature, &rt_f_element);
  347. break;
  348. case MISC_INFO_C2K:
  349. rt_feature.data_len = sizeof(struct ccci_misc_info_element);
  350. #ifdef FEATURE_C2K_ALWAYS_ON
  351. rt_f_element.feature[0] = (0
  352. #ifdef CONFIG_MTK_C2K_SUPPORT
  353. | (1 << 0)
  354. #endif
  355. #ifdef CONFIG_MTK_SVLTE_SUPPORT
  356. | (1 << 1)
  357. #endif
  358. #ifdef CONFIG_MTK_SRLTE_SUPPORT
  359. | (1 << 2)
  360. #endif
  361. #ifdef CONFIG_MTK_C2K_OM_SOLUTION1
  362. | (1 << 3)
  363. #endif
  364. #ifdef CONFIG_CT6M_SUPPORT
  365. | (1 << 4)
  366. #endif
  367. );
  368. #endif
  369. append_runtime_feature(&rt_data, &rt_feature, &rt_f_element);
  370. break;
  371. default:
  372. break;
  373. };
  374. } else {
  375. rt_feature.data_len = 0;
  376. append_runtime_feature(&rt_data, &rt_feature, NULL);
  377. }
  378. }
  379. total_len = rt_data - (char *)md->smem_layout.ccci_rt_smem_base_vir;
  380. /*ccci_mem_dump(md->index, md->smem_layout.ccci_rt_smem_base_vir, total_len);*/
  381. return 0;
  382. }
  383. #define PMIC_WRAP_MD_ADC_STA2 0x10001234
  384. #define INITFLOW_SEL 0x266031DC
  385. #define INITFLOW_RDY 0x266031E0
  386. #define INITFLOW_DBG 0x2660302C
  387. static void __iomem *pmic_wrap_md_adc_sta2;
  388. static void __iomem *md_initflow_sel;
  389. static void __iomem *md_initflow_rdy;
  390. static void __iomem *md_initflow_dbg;
  391. static void debug_register_map(void)
  392. {
  393. pmic_wrap_md_adc_sta2 = ioremap_nocache(PMIC_WRAP_MD_ADC_STA2, 4);
  394. md_initflow_sel = ioremap_nocache(INITFLOW_SEL, 4);
  395. md_initflow_rdy = ioremap_nocache(INITFLOW_RDY, 4);
  396. md_initflow_dbg = ioremap_nocache(INITFLOW_DBG, 4);
  397. }
  398. void dump_pmic_wrap_lte_register(struct ccci_modem *md)
  399. {
  400. unsigned int reg_value = 0;
  401. /*read pmic_wrap_md_adc_sta2*/
  402. CCCI_INF_MSG(md->index, KERN, "pmicwrap_md_adc_sta2: 0x%X\n",
  403. *((unsigned int *)pmic_wrap_md_adc_sta2));
  404. /*read sel & rdy*/
  405. CCCI_INF_MSG(md->index, KERN, "md_initflow: sel=0x%X, rdy=0x%X\n",
  406. *((unsigned int *)md_initflow_sel), *((unsigned int *)md_initflow_rdy));
  407. /*write dbg[3..0]=0xf & read dbg*/
  408. reg_value = *((unsigned int *)md_initflow_dbg);
  409. reg_value |= 0xF;
  410. *((unsigned int *)md_initflow_dbg) = reg_value;
  411. CCCI_INF_MSG(md->index, KERN, "md_initflow: dbg=0x%X\n",
  412. *((unsigned int *)md_initflow_dbg));
  413. /*write dbg[3..0]=0x0*/
  414. reg_value = *((unsigned int *)md_initflow_dbg);
  415. reg_value &= ~(0xF);
  416. *((unsigned int *)md_initflow_dbg) = reg_value;
  417. /*read pmic_wrap_md_adc_sta2*/
  418. CCCI_INF_MSG(md->index, KERN, "pmicwrap_md_adc_sta2: 0x%X\n",
  419. *((unsigned int *)pmic_wrap_md_adc_sta2));
  420. }
  421. int ccci_notfiy_md_desense(struct ccci_modem *md)
  422. {
  423. int ret = -1;
  424. if (md->md_state == READY) {
  425. ret = ccci_send_msg_to_md(md, CCCI_SYSTEM_TX, MD_RF_DESENSE, md->rf_desense, 0);
  426. CCCI_INF_MSG(md->index, KERN, "Send desense(%d),ret=%d\n", md->rf_desense, ret);
  427. } else
  428. CCCI_INF_MSG(md->index, KERN, "Not send desense for md state=%d\n", md->md_state);
  429. return ret;
  430. }
  431. int ccci_update_rf_desense(struct ccci_modem *md, int rf_desense)
  432. {
  433. md->rf_desense = rf_desense;
  434. return ccci_notfiy_md_desense(md);
  435. }
  436. /*
  437. * all supported modems should follow these handshake messages as a protocol.
  438. * but we still can support un-usual modem by providing cutomed kernel_port_ops.
  439. */
  440. static void control_msg_handler(struct ccci_port *port, struct ccci_request *req)
  441. {
  442. struct ccci_modem *md = port->modem;
  443. struct ccci_header *ccci_h = (struct ccci_header *)req->skb->data;
  444. unsigned long flags;
  445. struct c2k_ctrl_port_msg *c2k_ctl_msg = NULL;
  446. char need_update_state = 0;
  447. CCCI_INF_MSG(md->index, KERN, "control message 0x%X,0x%X\n", ccci_h->data[1], ccci_h->reserved);
  448. if (ccci_h->data[1] == MD_INIT_START_BOOT
  449. && ccci_h->reserved == MD_INIT_CHK_ID && md->boot_stage == MD_BOOT_STAGE_0) {
  450. del_timer(&md->bootup_timer);
  451. md->boot_stage = MD_BOOT_STAGE_1;
  452. #ifdef MD_UMOLY_EE_SUPPORT
  453. md->flight_mode = MD_FIGHT_MODE_NONE; /* leave flight mode */
  454. #endif
  455. if (req->skb->len == sizeof(struct md_query_ap_feature) + sizeof(struct ccci_header))
  456. prepare_runtime_data(md, req);
  457. else if (req->skb->len == sizeof(struct ccci_header))
  458. CCCI_INF_MSG(md->index, KERN, "get old handshake message\n");
  459. else
  460. CCCI_ERR_MSG(md->index, KERN, "get invalid MD_QUERY_MSG, skb->len =%u\n", req->skb->len);
  461. #ifdef SET_EMI_STEP_BY_STAGE
  462. ccci_set_mem_access_protection_second_stage(md);
  463. #endif
  464. ccci_send_virtual_md_msg(md, CCCI_MONITOR_CH, CCCI_MD_MSG_BOOT_UP, 0);
  465. } else if (ccci_h->data[1] == MD_NORMAL_BOOT && md->boot_stage == MD_BOOT_STAGE_1) {
  466. dump_pmic_wrap_lte_register(md);
  467. del_timer(&md->bootup_timer);
  468. md->boot_stage = MD_BOOT_STAGE_2;
  469. md->ops->broadcast_state(md, READY);
  470. ccci_send_virtual_md_msg(md, CCCI_MONITOR_CH, CCCI_MD_MSG_BOOT_READY, 0);
  471. if (md->rf_desense)
  472. ccci_notfiy_md_desense(md);
  473. } else if (ccci_h->data[1] == MD_EX) {
  474. if (unlikely(ccci_h->reserved != MD_EX_CHK_ID)) {
  475. CCCI_ERR_MSG(md->index, KERN, "receive invalid MD_EX\n");
  476. } else {
  477. spin_lock_irqsave(&md->ctrl_lock, flags);
  478. md->ee_info_flag |= ((1 << MD_EE_FLOW_START) | (1 << MD_EE_MSG_GET) | (1 << MD_STATE_UPDATE) |
  479. (1 << MD_EE_TIME_OUT_SET));
  480. md->config.setting |= MD_SETTING_RELOAD;
  481. spin_unlock_irqrestore(&md->ctrl_lock, flags);
  482. del_timer(&md->bootup_timer);
  483. if (!MD_IN_DEBUG(md))
  484. mod_timer(&md->ex_monitor, jiffies + EX_TIMER_MD_EX * HZ);
  485. md->ops->broadcast_state(md, EXCEPTION);
  486. ccci_send_virtual_md_msg(md, CCCI_MONITOR_CH, CCCI_MD_MSG_EXCEPTION, 0);
  487. ccci_send_msg_to_md(md, CCCI_CONTROL_TX, MD_EX, MD_EX_CHK_ID, 1);
  488. CCCI_INF_MSG(md->index, KERN, "Disable WDT at exception enter.");
  489. md->ops->ee_callback(md, EE_FLAG_DISABLE_WDT);
  490. }
  491. } else if (ccci_h->data[1] == MD_EX_REC_OK) {
  492. if (unlikely
  493. (ccci_h->reserved != MD_EX_REC_OK_CHK_ID
  494. || req->skb->len < (sizeof(struct ccci_header) + sizeof(EX_LOG_T)))) {
  495. CCCI_ERR_MSG(md->index, KERN, "receive invalid MD_EX_REC_OK, resv=%x, len=%d\n",
  496. ccci_h->reserved, req->skb->len);
  497. } else {
  498. spin_lock_irqsave(&md->ctrl_lock, flags);
  499. md->ee_info_flag |= ((1 << MD_EE_FLOW_START) | (1 << MD_EE_OK_MSG_GET));
  500. if ((md->ee_info_flag & (1 << MD_STATE_UPDATE)) == 0) {
  501. md->ee_info_flag |= (1 << MD_STATE_UPDATE);
  502. md->ee_info_flag &= ~(1 << MD_EE_TIME_OUT_SET);
  503. md->config.setting |= MD_SETTING_RELOAD;
  504. need_update_state = 1;
  505. }
  506. spin_unlock_irqrestore(&md->ctrl_lock, flags);
  507. if (need_update_state) {
  508. CCCI_ERR_MSG(md->index, KERN, "get MD_EX_REC_OK without exception MD_EX\n");
  509. del_timer(&md->bootup_timer);
  510. md->ops->broadcast_state(md, EXCEPTION);
  511. }
  512. /* copy exception info */
  513. #ifdef MD_UMOLY_EE_SUPPORT
  514. if (md->index == MD_SYS1)
  515. memcpy(md->ex_pl_info, skb_pull(req->skb, sizeof(struct ccci_header)),
  516. MD_HS1_FAIL_DUMP_SIZE/* sizeof(EX_PL_LOG_T) */);
  517. else
  518. #endif
  519. memcpy(&md->ex_info, skb_pull(req->skb, sizeof(struct ccci_header)), sizeof(EX_LOG_T));
  520. mod_timer(&md->ex_monitor, jiffies);
  521. }
  522. } else if (ccci_h->data[1] == MD_EX_PASS) {
  523. /* dump share memory again to let MD check exception flow */
  524. mod_timer(&md->ex_monitor2, jiffies);
  525. } else if (ccci_h->data[1] == MD_INIT_START_BOOT
  526. && ccci_h->reserved == MD_INIT_CHK_ID && !(md->config.setting & MD_SETTING_FIRST_BOOT)) {
  527. md->boot_stage = MD_BOOT_STAGE_0;
  528. CCCI_ERR_MSG(md->index, KERN, "MD second bootup detected!\n");
  529. ccci_send_virtual_md_msg(md, CCCI_MONITOR_CH, CCCI_MD_MSG_RESET, 0);
  530. } else if (ccci_h->data[1] == MD_EX_RESUME) {
  531. memset(&md->debug_info, 0, sizeof(md->debug_info));
  532. md->debug_info.type = MD_EX_TYPE_EMI_CHECK;
  533. md->debug_info.name = "EMI_CHK";
  534. md->debug_info.data = *(ccci_msg_t *) ccci_h;
  535. md->ex_type = MD_EX_TYPE_EMI_CHECK;
  536. ccci_ee_info_dump(md);
  537. } else if (ccci_h->data[1] == CCCI_DRV_VER_ERROR) {
  538. CCCI_ERR_MSG(md->index, KERN, "AP CCCI driver version mis-match to MD!!\n");
  539. md->config.setting |= MD_SETTING_STOP_RETRY_BOOT;
  540. ccci_aed(md, 0, "AP/MD driver version mis-match\n", DB_OPT_DEFAULT);
  541. } else if (md->index == MD_SYS3 && ccci_h->data[1] == C2K_HB_MSG) {
  542. status_msg_handler(port, req);
  543. CCCI_INF_MSG(md->index, KERN, "heart beat msg received\n");
  544. return;
  545. } else if (ccci_h->data[1] == C2K_STATUS_IND_MSG && md->index == MD_SYS3) {
  546. c2k_ctl_msg = (struct c2k_ctrl_port_msg *)&ccci_h->reserved;
  547. CCCI_INF_MSG(md->index, KERN, "c2k status ind 0x%02x\n", c2k_ctl_msg->option);
  548. if (c2k_ctl_msg->option & 0x80) /*connect */
  549. md->dtr_state = 1;
  550. else /*disconnect */
  551. md->dtr_state = 0;
  552. } else if (ccci_h->data[1] == C2K_STATUS_QUERY_MSG && md->index == MD_SYS3) {
  553. c2k_ctl_msg = (struct c2k_ctrl_port_msg *)&ccci_h->reserved;
  554. CCCI_INF_MSG(md->index, KERN, "c2k status query 0x%02x\n", c2k_ctl_msg->option);
  555. if (c2k_ctl_msg->option & 0x80) /*connect */
  556. md->dtr_state = 1;
  557. else /*disconnect */
  558. md->dtr_state = 0;
  559. } else {
  560. CCCI_ERR_MSG(md->index, KERN, "receive unknown data from CCCI_CONTROL_RX = %d\n", ccci_h->data[1]);
  561. }
  562. req->policy = RECYCLE;
  563. ccci_free_req(req);
  564. }
  565. #ifdef TEST_MESSAGE_FOR_BRINGUP
  566. int ccci_notify_md_by_sys_msg(int md_id, unsigned int msg, unsigned int data)
  567. {
  568. int ret = 0;
  569. struct ccci_modem *md;
  570. int idx = 0; /* get modem informaton (in Bach ,callback are registered in modem 0) */
  571. md = ccci_get_modem_by_id(idx);
  572. return ret = ccci_send_msg_to_md(md, CCCI_SYSTEM_TX, msg, data, 1);
  573. }
  574. int ccci_sysmsg_echo_test(int md_id, int data)
  575. {
  576. CCCI_DBG_MSG(md_id, KERN, "system message: Enter ccci_sysmsg_echo_test data= %08x", data);
  577. ccci_notify_md_by_sys_msg(md_id, TEST_MSG_ID_AP2MD, data);
  578. return 0;
  579. }
  580. EXPORT_SYMBOL(ccci_sysmsg_echo_test);
  581. int ccci_sysmsg_echo_test_l1core(int md_id, int data)
  582. {
  583. CCCI_DBG_MSG(md_id, KERN, "system message: Enter ccci_sysmsg_echo_test_l1core data= %08x", data);
  584. ccci_notify_md_by_sys_msg(md_id, TEST_MSG_ID_L1CORE_AP2MD, data);
  585. return 0;
  586. }
  587. EXPORT_SYMBOL(ccci_sysmsg_echo_test_l1core);
  588. #endif
  589. /* for backward compatibility */
  590. ccci_sys_cb_func_info_t ccci_sys_cb_table_100[MAX_MD_NUM][MAX_KERN_API];
  591. ccci_sys_cb_func_info_t ccci_sys_cb_table_1000[MAX_MD_NUM][MAX_KERN_API];
  592. int register_ccci_sys_call_back(int md_id, unsigned int id, ccci_sys_cb_func_t func)
  593. {
  594. int ret = 0;
  595. ccci_sys_cb_func_info_t *info_ptr;
  596. if (md_id >= MAX_MD_NUM) {
  597. CCCI_ERR_MSG(md_id, KERN, "register_sys_call_back fail: invalid md id\n");
  598. return -EINVAL;
  599. }
  600. if ((id >= 0x100) && ((id - 0x100) < MAX_KERN_API)) {
  601. info_ptr = &(ccci_sys_cb_table_100[md_id][id - 0x100]);
  602. } else if ((id >= 0x1000) && ((id - 0x1000) < MAX_KERN_API)) {
  603. info_ptr = &(ccci_sys_cb_table_1000[md_id][id - 0x1000]);
  604. } else {
  605. CCCI_ERR_MSG(md_id, KERN, "register_sys_call_back fail: invalid func id(0x%x)\n", id);
  606. return -EINVAL;
  607. }
  608. if (info_ptr->func == NULL) {
  609. info_ptr->id = id;
  610. info_ptr->func = func;
  611. } else {
  612. CCCI_ERR_MSG(md_id, KERN, "register_sys_call_back fail: func(0x%x) registered!\n", id);
  613. }
  614. return ret;
  615. }
  616. void exec_ccci_sys_call_back(int md_id, int cb_id, int data)
  617. {
  618. ccci_sys_cb_func_t func;
  619. int id;
  620. ccci_sys_cb_func_info_t *curr_table;
  621. if (md_id >= MAX_MD_NUM) {
  622. CCCI_ERR_MSG(md_id, KERN, "exec_sys_cb fail: invalid md id\n");
  623. return;
  624. }
  625. id = cb_id & 0xFF;
  626. if (id >= MAX_KERN_API) {
  627. CCCI_ERR_MSG(md_id, KERN, "exec_sys_cb fail: invalid func id(0x%x)\n", cb_id);
  628. return;
  629. }
  630. if ((cb_id & (0x1000 | 0x100)) == 0x1000) {
  631. curr_table = ccci_sys_cb_table_1000[md_id];
  632. } else if ((cb_id & (0x1000 | 0x100)) == 0x100) {
  633. curr_table = ccci_sys_cb_table_100[md_id];
  634. } else {
  635. CCCI_ERR_MSG(md_id, KERN, "exec_sys_cb fail: invalid func id(0x%x)\n", cb_id);
  636. return;
  637. }
  638. func = curr_table[id].func;
  639. if (func != NULL)
  640. func(md_id, data);
  641. else
  642. CCCI_ERR_MSG(md_id, KERN, "exec_sys_cb fail: func id(0x%x) not register!\n", cb_id);
  643. }
  644. static void system_msg_handler(struct ccci_port *port, struct ccci_request *req)
  645. {
  646. struct ccci_modem *md = port->modem;
  647. struct ccci_header *ccci_h = (struct ccci_header *)req->skb->data;
  648. CCCI_DBG_MSG(md->index, KERN, "system message (%x %x %x %x)\n", ccci_h->data[0], ccci_h->data[1],
  649. ccci_h->channel, ccci_h->reserved);
  650. switch (ccci_h->data[1]) {
  651. case MD_GET_BATTERY_INFO:
  652. ccci_send_virtual_md_msg(md, CCCI_MONITOR_CH, CCCI_MD_MSG_SEND_BATTERY_INFO, 0);
  653. break;
  654. case MD_WDT_MONITOR:
  655. /* abandoned */
  656. break;
  657. case MD_SIM_TYPE:
  658. md->sim_type = ccci_h->reserved;
  659. CCCI_INF_MSG(md->index, KERN, "MD send sys msg sim type(0x%x)\n", md->sim_type);
  660. break;
  661. case MD_TX_POWER:
  662. case MD_RF_TEMPERATURE:
  663. case MD_RF_TEMPERATURE_3G:
  664. #if defined(CONFIG_MTK_SWITCH_TX_POWER)
  665. case MD_SW_MD1_TX_POWER_REQ:
  666. case MD_SW_MD2_TX_POWER_REQ:
  667. #endif
  668. #ifdef TEST_MESSAGE_FOR_BRINGUP
  669. /* Fall through */
  670. case TEST_MSG_ID_MD2AP:
  671. /* Fall through */
  672. case TEST_MSG_ID_AP2MD:
  673. /* Fall through */
  674. case TEST_MSG_ID_L1CORE_MD2AP:
  675. /* Fall through */
  676. case TEST_MSG_ID_L1CORE_AP2MD:
  677. #endif
  678. exec_ccci_sys_call_back(md->index, ccci_h->data[1], ccci_h->reserved);
  679. break;
  680. };
  681. req->policy = RECYCLE;
  682. ccci_free_req(req);
  683. }
  684. static int get_md_gpio_val(unsigned int num)
  685. {
  686. #if defined(FEATURE_GET_MD_GPIO_VAL)
  687. #if defined(CONFIG_MTK_LEGACY)
  688. return mt_get_gpio_in(num);
  689. #else
  690. return __gpio_get_value(num);
  691. #endif
  692. #else
  693. return -1;
  694. #endif
  695. }
  696. static int get_md_adc_val(unsigned int num)
  697. {
  698. int ret = -1;
  699. #if defined(FEATURE_GET_MD_ADC_VAL)
  700. int data[4] = { 0, 0, 0, 0 };
  701. int val = 0;
  702. ret = IMM_GetOneChannelValue(num, data, &val);
  703. CCCI_DBG_MSG(0, RPC, "FEATURE_GET_MD_ADC_VAL,ret=%d, val=%d\n", ret, val);
  704. if (ret == 0)
  705. return val;
  706. else
  707. return ret;
  708. #elif defined(FEATURE_GET_MD_PMIC_ADC_VAL)
  709. ret = PMIC_IMM_GetOneChannelValue(num, 1, 0);
  710. CCCI_DBG_MSG(0, RPC, "FEATURE_GET_MD_PMIC_ADC_VAL, %d\n", ret);
  711. return ret;
  712. #else
  713. CCCI_INF_MSG(0, RPC, "FEATURE GET MD ADC not def %d\n", ret);
  714. return ret;
  715. #endif
  716. }
  717. static int get_td_eint_info(char *eint_name, unsigned int len)
  718. {
  719. #if defined(FEATURE_GET_TD_EINT_NUM)
  720. return get_td_eint_num(eint_name, len);
  721. #else
  722. return -1;
  723. #endif
  724. }
  725. static int get_md_adc_info(char *adc_name, unsigned int len)
  726. {
  727. int ret = 0;
  728. #if defined(FEATURE_GET_MD_ADC_NUM)
  729. ret = IMM_get_adc_channel_num(adc_name, len);
  730. CCCI_DBG_MSG(0, RPC, "IMM_get_adc_channel_num, %d\n", ret);
  731. #elif defined(FEATURE_GET_MD_PMIC_ADC_NUM)
  732. ret = PMIC_IMM_get_adc_channel_num(adc_name, len);
  733. CCCI_DBG_MSG(0, RPC, "PMIC_IMM_get_adc_channel_num, %d\n", ret);
  734. #else
  735. ret = -1;
  736. CCCI_INF_MSG(0, RPC, "FEATURE_GET_MD_ADC_VAL not def %d\n", ret);
  737. #endif
  738. return ret;
  739. }
  740. static int get_md_gpio_info(char *gpio_name, unsigned int len)
  741. {
  742. #if defined(FEATURE_GET_MD_GPIO_NUM)
  743. int i = 0;
  744. struct device_node *node = of_find_compatible_node(NULL, NULL, "mediatek,gpio_usage_mapping");
  745. int gpio_id = -1;
  746. if (!node) {
  747. CCCI_INF_MSG(0, RPC, "MD_USE_GPIO is not set in device tree,need to check?\n");
  748. return gpio_id;
  749. }
  750. CCCI_INF_MSG(0, RPC, "looking for %s id, len %d\n", gpio_name, len);
  751. for (i = 0; i < ARRAY_SIZE(gpio_mapping_table); i++) {
  752. CCCI_DBG_MSG(0, RPC, "compare with %s\n", gpio_mapping_table[i].gpio_name_from_md);
  753. if (!strncmp(gpio_name, gpio_mapping_table[i].gpio_name_from_md, len)) {
  754. CCCI_INF_MSG(0, RPC, "searching %s in device tree\n", gpio_mapping_table[i].gpio_name_from_dts);
  755. of_property_read_u32(node, gpio_mapping_table[i].gpio_name_from_dts, &gpio_id);
  756. break;
  757. }
  758. }
  759. /* if gpio_name_from_md and gpio_name_from_dts are the same,
  760. it will not be listed in gpio_mapping_table,
  761. so try read directly from device tree here.
  762. */
  763. if (gpio_id < 0) {
  764. CCCI_INF_MSG(0, RPC, "try directly get id from device tree\n");
  765. of_property_read_u32(node, gpio_name, &gpio_id);
  766. }
  767. CCCI_INF_MSG(0, RPC, "%s id %d\n", gpio_name, gpio_id);
  768. return gpio_id;
  769. #else
  770. return -1;
  771. #endif
  772. }
  773. static int get_dram_type_clk(int *clk, int *type)
  774. {
  775. #if defined(FEATURE_GET_DRAM_TYPE_CLK)
  776. return get_dram_info(clk, type);
  777. #else
  778. return -1;
  779. #endif
  780. }
  781. #ifdef FEATURE_GET_MD_EINT_ATTR_DTS
  782. static struct eint_struct md_eint_struct[] = {
  783. /* ID of MD get, property name, cell index read from property */
  784. {SIM_HOT_PLUG_EINT_NUMBER, "interrupts", 0,},
  785. {SIM_HOT_PLUG_EINT_DEBOUNCETIME, "debounce", 1,},
  786. {SIM_HOT_PLUG_EINT_POLARITY, "interrupts", 1,},
  787. {SIM_HOT_PLUG_EINT_SENSITIVITY, "interrupts", 1,},
  788. {SIM_HOT_PLUG_EINT_SOCKETTYPE, "sockettype", 1,},
  789. {SIM_HOT_PLUG_EINT_DEDICATEDEN, "dedicated", 1,},
  790. {SIM_HOT_PLUG_EINT_SRCPIN, "src_pin", 1,},
  791. {SIM_HOT_PLUG_EINT_MAX, "invalid_type", 0xFF,},
  792. };
  793. static struct eint_node_name md_eint_node[] = {
  794. {"MD1_SIM1_HOT_PLUG_EINT", 1, 1,},
  795. {"MD1_SIM2_HOT_PLUG_EINT", 1, 2,},
  796. {"MD1_SIM3_HOT_PLUG_EINT", 1, 3,},
  797. {"MD1_SIM4_HOT_PLUG_EINT", 1, 4,},
  798. /* {"MD1_SIM5_HOT_PLUG_EINT", 1, 5, }, */
  799. /* {"MD1_SIM6_HOT_PLUG_EINT", 1, 6, }, */
  800. /* {"MD1_SIM7_HOT_PLUG_EINT", 1, 7, }, */
  801. /* {"MD1_SIM8_HOT_PLUG_EINT", 1, 8, }, */
  802. /* {"MD2_SIM1_HOT_PLUG_EINT", 2, 1, }, */
  803. /* {"MD2_SIM2_HOT_PLUG_EINT", 2, 2, }, */
  804. /* {"MD2_SIM3_HOT_PLUG_EINT", 2, 3, }, */
  805. /* {"MD2_SIM4_HOT_PLUG_EINT", 2, 4, }, */
  806. /* {"MD2_SIM5_HOT_PLUG_EINT", 2, 5, }, */
  807. /* {"MD2_SIM6_HOT_PLUG_EINT", 2, 6, }, */
  808. /* {"MD2_SIM7_HOT_PLUG_EINT", 2, 7, }, */
  809. /* {"MD2_SIM8_HOT_PLUG_EINT", 2, 8, }, */
  810. {NULL,},
  811. };
  812. struct eint_node_struct eint_node_prop = {
  813. 0,
  814. md_eint_node,
  815. md_eint_struct,
  816. };
  817. static int get_eint_attr_val(struct device_node *node, int index)
  818. {
  819. int value;
  820. int ret = 0, type;
  821. int covert_AP_to_MD_unit = 1000; /*unit of AP eint is us, but unit of MD eint is ms. So need covertion here.*/
  822. for (type = 0; type < SIM_HOT_PLUG_EINT_MAX; type++) {
  823. ret = of_property_read_u32_index(node, md_eint_struct[type].property,
  824. md_eint_struct[type].index, &value);
  825. if (!ret) {
  826. /* special case: polarity's position == sensitivity's start[ */
  827. if (type == SIM_HOT_PLUG_EINT_POLARITY) {
  828. switch (value) {
  829. case IRQ_TYPE_EDGE_RISING:
  830. case IRQ_TYPE_EDGE_FALLING:
  831. case IRQ_TYPE_LEVEL_HIGH:
  832. case IRQ_TYPE_LEVEL_LOW:
  833. md_eint_struct[SIM_HOT_PLUG_EINT_POLARITY].value_sim[index] =
  834. (value & 0x5) ? 1 : 0;
  835. /*1/4: IRQ_TYPE_EDGE_RISING/IRQ_TYPE_LEVEL_HIGH Set 1 */
  836. md_eint_struct[SIM_HOT_PLUG_EINT_SENSITIVITY].value_sim[index] =
  837. (value & 0x3) ? 1 : 0;
  838. /*1/2: IRQ_TYPE_EDGE_RISING/IRQ_TYPE_LEVEL_FALLING Set 1 */
  839. break;
  840. default: /* invalid */
  841. md_eint_struct[SIM_HOT_PLUG_EINT_POLARITY].value_sim[index] = -1;
  842. md_eint_struct[SIM_HOT_PLUG_EINT_SENSITIVITY].value_sim[index] = -1;
  843. CCCI_ERR_MSG(-1, RPC, "invalid value, please check dtsi!\n");
  844. break;
  845. }
  846. /* CCCI_INF_MSG(-1, RPC, "%s: --- %d_%d_%d\n", md_eint_struct[type].property,
  847. md_eint_struct[type].index,
  848. md_eint_struct[SIM_HOT_PLUG_EINT_POLARITY].value_sim[index],
  849. md_eint_struct[SIM_HOT_PLUG_EINT_SENSITIVITY].value_sim[index]); */
  850. type++;
  851. } else if (type == SIM_HOT_PLUG_EINT_DEBOUNCETIME) {
  852. /*debounce time should divide by 1000 due to different unit in AP and MD.*/
  853. md_eint_struct[type].value_sim[index] = value/covert_AP_to_MD_unit;
  854. } else {
  855. md_eint_struct[type].value_sim[index] = value;
  856. /* CCCI_INF_MSG(-1, RPC, "%s: --- %d_%d\n", md_eint_struct[type].property,
  857. md_eint_struct[type].index, md_eint_struct[type].value_sim[index]); */
  858. }
  859. } else {
  860. md_eint_struct[type].value_sim[index] = ERR_SIM_HOT_PLUG_QUERY_TYPE;
  861. CCCI_INF_MSG(-1, RPC, "%s: not found\n", md_eint_struct[type].property);
  862. return ERR_SIM_HOT_PLUG_QUERY_TYPE;
  863. }
  864. }
  865. return 0;
  866. }
  867. void get_dtsi_eint_node(void)
  868. {
  869. int i;
  870. struct device_node *node;
  871. for (i = 0; i < MD_SIM_MAX; i++) {
  872. if (eint_node_prop.name[i].node_name != NULL) {
  873. /* CCCI_INF_MSG(-1, TAG, "node_%d__ %d\n", i,
  874. (int)(strlen(eint_node_prop.name[i].node_name))); */
  875. if (strlen(eint_node_prop.name[i].node_name) > 0) {
  876. /* CCCI_INF_MSG(-1, TAG, "found %s: node %d\n", eint_node_prop.name[i].node_name, i); */
  877. node = of_find_node_by_name(NULL, eint_node_prop.name[i].node_name);
  878. if (node != NULL) {
  879. eint_node_prop.ExistFlag |= (1 << i);
  880. get_eint_attr_val(node, i);
  881. /* CCCI_INF_MSG(-1, TAG, "%s: node %d found\n", eint_node_prop.name[i], i); */
  882. } else {
  883. CCCI_INF_MSG(-1, RPC, "%s: node %d no found\n",
  884. eint_node_prop.name[i].node_name, i);
  885. }
  886. }
  887. } else {
  888. CCCI_INF_MSG(-1, RPC, "node %d is NULL\n", i);
  889. break;
  890. }
  891. }
  892. }
  893. int get_eint_attr_DTSVal(char *name, unsigned int name_len, unsigned int type, char *result, unsigned int *len)
  894. {
  895. int i, sim_value;
  896. int *sim_info = (int *)result;
  897. if ((name == NULL) || (result == NULL) || (len == NULL))
  898. return ERR_SIM_HOT_PLUG_NULL_POINTER;
  899. /* CCCI_INF_MSG(-1, KERN, "get_eint_value: %s\n", name); */
  900. if (type >= SIM_HOT_PLUG_EINT_MAX)
  901. return ERR_SIM_HOT_PLUG_QUERY_TYPE;
  902. /* CCCI_INF_MSG(-1, RPC, "get_eint_value:%s, %d\n", name, eint_node_prop.ExistFlag); */
  903. for (i = 0; i < MD_SIM_MAX; i++) {
  904. if (eint_node_prop.ExistFlag & (1 << i)) {
  905. if (!(strncmp(name, eint_node_prop.name[i].node_name, name_len))) {
  906. sim_value = eint_node_prop.eint_value[type].value_sim[i];
  907. *len = sizeof(sim_value);
  908. memcpy(sim_info, &sim_value, *len);
  909. /* CCCI_INF_MSG(-1, RPC, "get_eint_value type name:%s,
  910. sizeof: %d, sim_info: %d, %d\n", eint_node_prop.eint_value[type].property,
  911. *len, *sim_info, eint_node_prop.eint_value[type].value_sim[i]); */
  912. return 0;
  913. }
  914. }
  915. }
  916. return ERR_SIM_HOT_PLUG_QUERY_STRING;
  917. }
  918. #endif
  919. static int get_eint_attr(char *name, unsigned int name_len, unsigned int type, char *result, unsigned int *len)
  920. {
  921. #ifdef FEATURE_GET_MD_EINT_ATTR_DTS
  922. return get_eint_attr_DTSVal(name, name_len, type, result, len);
  923. #else
  924. #if defined(FEATURE_GET_MD_EINT_ATTR)
  925. return get_eint_attribute(name, name_len, type, result, len);
  926. #else
  927. return -1;
  928. #endif
  929. #endif
  930. }
  931. static void ccci_rpc_get_gpio_adc(struct ccci_rpc_gpio_adc_intput *input, struct ccci_rpc_gpio_adc_output *output)
  932. {
  933. int num;
  934. unsigned int val, i;
  935. CCCI_INF_MSG(0, KERN, "IPC_RPC_GET_GPIO_ADC_OP reqMask=%x\n", input->reqMask);
  936. if ((input->reqMask & (RPC_REQ_GPIO_PIN | RPC_REQ_GPIO_VALUE)) == (RPC_REQ_GPIO_PIN | RPC_REQ_GPIO_VALUE)) {
  937. for (i = 0; i < GPIO_MAX_COUNT; i++) {
  938. if (input->gpioValidPinMask & (1 << i)) {
  939. num = get_md_gpio_info(input->gpioPinName[i], strlen(input->gpioPinName[i]));
  940. if (num >= 0) {
  941. output->gpioPinNum[i] = num;
  942. val = get_md_gpio_val(num);
  943. output->gpioPinValue[i] = val;
  944. }
  945. }
  946. }
  947. } else {
  948. if (input->reqMask & RPC_REQ_GPIO_PIN) {
  949. for (i = 0; i < GPIO_MAX_COUNT; i++) {
  950. if (input->gpioValidPinMask & (1 << i)) {
  951. num = get_md_gpio_info(input->gpioPinName[i], strlen(input->gpioPinName[i]));
  952. if (num >= 0)
  953. output->gpioPinNum[i] = num;
  954. }
  955. }
  956. }
  957. if (input->reqMask & RPC_REQ_GPIO_VALUE) {
  958. for (i = 0; i < GPIO_MAX_COUNT; i++) {
  959. if (input->gpioValidPinMask & (1 << i)) {
  960. val = get_md_gpio_val(input->gpioPinNum[i]);
  961. output->gpioPinValue[i] = val;
  962. }
  963. }
  964. }
  965. }
  966. if ((input->reqMask & (RPC_REQ_ADC_PIN | RPC_REQ_ADC_VALUE)) == (RPC_REQ_ADC_PIN | RPC_REQ_ADC_VALUE)) {
  967. num = get_md_adc_info(input->adcChName, strlen(input->adcChName));
  968. if (num >= 0) {
  969. output->adcChNum = num;
  970. output->adcChMeasSum = 0;
  971. for (i = 0; i < input->adcChMeasCount; i++) {
  972. val = get_md_adc_val(num);
  973. output->adcChMeasSum += val;
  974. }
  975. }
  976. } else {
  977. if (input->reqMask & RPC_REQ_ADC_PIN) {
  978. num = get_md_adc_info(input->adcChName, strlen(input->adcChName));
  979. if (num >= 0)
  980. output->adcChNum = num;
  981. }
  982. if (input->reqMask & RPC_REQ_ADC_VALUE) {
  983. output->adcChMeasSum = 0;
  984. for (i = 0; i < input->adcChMeasCount; i++) {
  985. val = get_md_adc_val(input->adcChNum);
  986. output->adcChMeasSum += val;
  987. }
  988. }
  989. }
  990. }
  991. static void ccci_rpc_get_gpio_adc_v2(struct ccci_rpc_gpio_adc_intput_v2 *input,
  992. struct ccci_rpc_gpio_adc_output_v2 *output)
  993. {
  994. int num;
  995. unsigned int val, i;
  996. if ((input->reqMask & (RPC_REQ_GPIO_PIN | RPC_REQ_GPIO_VALUE)) == (RPC_REQ_GPIO_PIN | RPC_REQ_GPIO_VALUE)) {
  997. for (i = 0; i < GPIO_MAX_COUNT_V2; i++) {
  998. if (input->gpioValidPinMask & (1 << i)) {
  999. num = get_md_gpio_info(input->gpioPinName[i], strlen(input->gpioPinName[i]));
  1000. if (num >= 0) {
  1001. output->gpioPinNum[i] = num;
  1002. val = get_md_gpio_val(num);
  1003. output->gpioPinValue[i] = val;
  1004. }
  1005. }
  1006. }
  1007. } else {
  1008. if (input->reqMask & RPC_REQ_GPIO_PIN) {
  1009. for (i = 0; i < GPIO_MAX_COUNT_V2; i++) {
  1010. if (input->gpioValidPinMask & (1 << i)) {
  1011. num = get_md_gpio_info(input->gpioPinName[i], strlen(input->gpioPinName[i]));
  1012. if (num >= 0)
  1013. output->gpioPinNum[i] = num;
  1014. }
  1015. }
  1016. }
  1017. if (input->reqMask & RPC_REQ_GPIO_VALUE) {
  1018. for (i = 0; i < GPIO_MAX_COUNT_V2; i++) {
  1019. if (input->gpioValidPinMask & (1 << i)) {
  1020. val = get_md_gpio_val(input->gpioPinNum[i]);
  1021. output->gpioPinValue[i] = val;
  1022. }
  1023. }
  1024. }
  1025. }
  1026. if ((input->reqMask & (RPC_REQ_ADC_PIN | RPC_REQ_ADC_VALUE)) == (RPC_REQ_ADC_PIN | RPC_REQ_ADC_VALUE)) {
  1027. num = get_md_adc_info(input->adcChName, strlen(input->adcChName));
  1028. if (num >= 0) {
  1029. output->adcChNum = num;
  1030. output->adcChMeasSum = 0;
  1031. for (i = 0; i < input->adcChMeasCount; i++) {
  1032. val = get_md_adc_val(num);
  1033. output->adcChMeasSum += val;
  1034. }
  1035. }
  1036. } else {
  1037. if (input->reqMask & RPC_REQ_ADC_PIN) {
  1038. num = get_md_adc_info(input->adcChName, strlen(input->adcChName));
  1039. if (num >= 0)
  1040. output->adcChNum = num;
  1041. }
  1042. if (input->reqMask & RPC_REQ_ADC_VALUE) {
  1043. output->adcChMeasSum = 0;
  1044. for (i = 0; i < input->adcChMeasCount; i++) {
  1045. val = get_md_adc_val(input->adcChNum);
  1046. output->adcChMeasSum += val;
  1047. }
  1048. }
  1049. }
  1050. }
  1051. static void ccci_rpc_work_helper(struct ccci_modem *md, struct rpc_pkt *pkt,
  1052. struct rpc_buffer *p_rpc_buf, unsigned int tmp_data[])
  1053. {
  1054. /* tmp_data[] is used to make sure memory address is valid
  1055. after this function return, be careful with the size! */
  1056. int pkt_num = p_rpc_buf->para_num;
  1057. CCCI_DBG_MSG(md->index, RPC, "ccci_rpc_work_helper++ %d\n", p_rpc_buf->para_num);
  1058. tmp_data[0] = 0;
  1059. switch (p_rpc_buf->op_id) {
  1060. case IPC_RPC_CPSVC_SECURE_ALGO_OP:
  1061. {
  1062. unsigned char Direction = 0;
  1063. unsigned long ContentAddr = 0;
  1064. unsigned int ContentLen = 0;
  1065. sed_t CustomSeed = SED_INITIALIZER;
  1066. unsigned char *ResText __always_unused;
  1067. unsigned char *RawText __always_unused;
  1068. unsigned int i __always_unused;
  1069. if (pkt_num < 4 || pkt_num >= RPC_MAX_ARG_NUM) {
  1070. CCCI_ERR_MSG(md->index, RPC, "invalid pkt_num %d for RPC_SECURE_ALGO_OP!\n", pkt_num);
  1071. tmp_data[0] = FS_PARAM_ERROR;
  1072. pkt_num = 0;
  1073. pkt[pkt_num].len = sizeof(unsigned int);
  1074. pkt[pkt_num++].buf = (void *)&tmp_data[0];
  1075. break;
  1076. }
  1077. Direction = *(unsigned char *)pkt[0].buf;
  1078. ContentAddr = (unsigned long)pkt[1].buf;
  1079. CCCI_DBG_MSG(md->index, RPC,
  1080. "RPC_SECURE_ALGO_OP: Content_Addr = 0x%p, RPC_Base = 0x%p, RPC_Len = 0x%zu\n",
  1081. (void *)ContentAddr, p_rpc_buf, sizeof(unsigned int) + RPC_MAX_BUF_SIZE);
  1082. if (ContentAddr < (unsigned long)p_rpc_buf
  1083. || ContentAddr > ((unsigned long)p_rpc_buf + sizeof(unsigned int) + RPC_MAX_BUF_SIZE)) {
  1084. CCCI_ERR_MSG(md->index, RPC, "invalid ContentAdddr[0x%p] for RPC_SECURE_ALGO_OP!\n",
  1085. (void *)ContentAddr);
  1086. tmp_data[0] = FS_PARAM_ERROR;
  1087. pkt[pkt_num].len = sizeof(unsigned int);
  1088. pkt[pkt_num++].buf = (void *)&tmp_data[0];
  1089. break;
  1090. }
  1091. ContentLen = *(unsigned int *)pkt[2].buf;
  1092. /* CustomSeed = *(sed_t*)pkt[3].buf; */
  1093. WARN_ON(sizeof(CustomSeed.sed) < pkt[3].len);
  1094. memcpy(CustomSeed.sed, pkt[3].buf, pkt[3].len);
  1095. #ifdef ENCRYPT_DEBUG
  1096. unsigned char log_buf[128];
  1097. int curr;
  1098. if (Direction == TRUE)
  1099. CCCI_DBG_MSG(md->index, RPC, "HACC_S: EnCrypt_src:\n");
  1100. else
  1101. CCCI_DBG_MSG(md->index, RPC, "HACC_S: DeCrypt_src:\n");
  1102. for (i = 0; i < ContentLen; i++) {
  1103. if (i % 16 == 0) {
  1104. if (i != 0)
  1105. CCCI_INF_MSG(md->index, RPC, "%s\n", log_buf);
  1106. curr = 0;
  1107. curr += snprintf(log_buf, sizeof(log_buf) - curr, "HACC_S: ");
  1108. }
  1109. /* CCCI_INF_MSG(md->index, RPC, "0x%02X ", *(unsigned char*)(ContentAddr+i)); */
  1110. curr +=
  1111. snprintf(&log_buf[curr], sizeof(log_buf) - curr, "0x%02X ",
  1112. *(unsigned char *)(ContentAddr + i));
  1113. /* sleep(1); */
  1114. }
  1115. CCCI_INF_MSG(md->index, RPC, "%s\n", log_buf);
  1116. RawText = kmalloc(ContentLen, GFP_KERNEL);
  1117. if (RawText == NULL)
  1118. CCCI_ERR_MSG(md->index, RPC, "Fail alloc Mem for RPC_SECURE_ALGO_OP!\n");
  1119. else
  1120. memcpy(RawText, (unsigned char *)ContentAddr, ContentLen);
  1121. #endif
  1122. ResText = kmalloc(ContentLen, GFP_KERNEL);
  1123. if (ResText == NULL) {
  1124. CCCI_ERR_MSG(md->index, RPC, "Fail alloc Mem for RPC_SECURE_ALGO_OP!\n");
  1125. tmp_data[0] = FS_PARAM_ERROR;
  1126. pkt[pkt_num].len = sizeof(unsigned int);
  1127. pkt[pkt_num++].buf = (void *)&tmp_data[0];
  1128. break;
  1129. }
  1130. #if (defined(ENABLE_MD_IMG_SECURITY_FEATURE) && defined(MTK_SEC_MODEM_NVRAM_ANTI_CLONE))
  1131. if (!masp_secure_algo_init()) {
  1132. CCCI_ERR_MSG(md->index, RPC, "masp_secure_algo_init fail!\n");
  1133. BUG_ON(1);
  1134. }
  1135. CCCI_DBG_MSG(md->index, RPC,
  1136. "RPC_SECURE_ALGO_OP: Dir=0x%08X, Addr=0x%08lX, Len=0x%08X, Seed=0x%016llX\n",
  1137. Direction, ContentAddr, ContentLen, *(long long *)CustomSeed.sed);
  1138. masp_secure_algo(Direction, (unsigned char *)ContentAddr, ContentLen, CustomSeed.sed, ResText);
  1139. if (!masp_secure_algo_deinit())
  1140. CCCI_ERR_MSG(md->index, RPC, "masp_secure_algo_deinit fail!\n");
  1141. #endif
  1142. pkt_num = 0;
  1143. pkt[pkt_num].len = sizeof(unsigned int);
  1144. pkt[pkt_num++].buf = (void *)&tmp_data[0];
  1145. pkt[pkt_num].len = ContentLen;
  1146. #if (defined(ENABLE_MD_IMG_SECURITY_FEATURE) && defined(MTK_SEC_MODEM_NVRAM_ANTI_CLONE))
  1147. memcpy(pkt[pkt_num++].buf, ResText, ContentLen);
  1148. CCCI_DBG_MSG(md->index, RPC, "RPC_Secure memory copy OK: %d!", ContentLen);
  1149. #else
  1150. memcpy(pkt[pkt_num++].buf, (void *)ContentAddr, ContentLen);
  1151. CCCI_DBG_MSG(md->index, RPC, "RPC_NORMAL memory copy OK: %d!", ContentLen);
  1152. #endif
  1153. #ifdef ENCRYPT_DEBUG
  1154. if (Direction == TRUE)
  1155. CCCI_DBG_MSG(md->index, RPC, "HACC_D: EnCrypt_dst:\n");
  1156. else
  1157. CCCI_DBG_MSG(md->index, RPC, "HACC_D: DeCrypt_dst:\n");
  1158. for (i = 0; i < ContentLen; i++) {
  1159. if (i % 16 == 0) {
  1160. if (i != 0)
  1161. CCCI_DBG_MSG(md->index, RPC, "%s\n", log_buf);
  1162. curr = 0;
  1163. curr += snprintf(&log_buf[curr], sizeof(log_buf) - curr, "HACC_D: ");
  1164. }
  1165. /* CCCI_INF_MSG(md->index, RPC, "%02X ", *(ResText+i)); */
  1166. curr += snprintf(&log_buf[curr], sizeof(log_buf) - curr, "0x%02X ", *(ResText + i));
  1167. /* sleep(1); */
  1168. }
  1169. CCCI_DBG_MSG(md->index, RPC, "%s\n", log_buf);
  1170. kfree(RawText);
  1171. #endif
  1172. kfree(ResText);
  1173. break;
  1174. }
  1175. #ifdef ENABLE_MD_IMG_SECURITY_FEATURE
  1176. case IPC_RPC_GET_SECRO_OP:
  1177. {
  1178. unsigned char *addr = NULL;
  1179. unsigned int img_len = 0;
  1180. unsigned int img_len_bak = 0;
  1181. unsigned int blk_sz = 0;
  1182. unsigned int tmp = 1;
  1183. unsigned int cnt = 0;
  1184. unsigned int req_len = 0;
  1185. if (pkt_num != 1) {
  1186. CCCI_ERR_MSG(md->index, RPC, "RPC_GET_SECRO_OP: invalid parameter: pkt_num=%d\n",
  1187. pkt_num);
  1188. tmp_data[0] = FS_PARAM_ERROR;
  1189. pkt_num = 0;
  1190. pkt[pkt_num].len = sizeof(unsigned int);
  1191. pkt[pkt_num++].buf = (void *)&tmp_data[0];
  1192. pkt[pkt_num].len = sizeof(unsigned int);
  1193. tmp_data[1] = img_len;
  1194. pkt[pkt_num++].buf = (void *)&tmp_data[1];
  1195. break;
  1196. }
  1197. req_len = *(unsigned int *)(pkt[0].buf);
  1198. if (masp_secro_en()) {
  1199. img_len = masp_secro_md_len(md->post_fix);
  1200. if ((img_len > RPC_MAX_BUF_SIZE) || (req_len > RPC_MAX_BUF_SIZE)) {
  1201. pkt_num = 0;
  1202. tmp_data[0] = FS_MEM_OVERFLOW;
  1203. pkt[pkt_num].len = sizeof(unsigned int);
  1204. pkt[pkt_num++].buf = (void *)&tmp_data[0];
  1205. /* set it as image length for modem ccci check when error happens */
  1206. pkt[pkt_num].len = img_len;
  1207. /* /pkt[pkt_num].len = sizeof(unsigned int); */
  1208. tmp_data[1] = img_len;
  1209. pkt[pkt_num++].buf = (void *)&tmp_data[1];
  1210. CCCI_ERR_MSG(md->index, RPC,
  1211. "RPC_GET_SECRO_OP: md request length is larger than rpc memory: (%d, %d)\n",
  1212. req_len, img_len);
  1213. break;
  1214. }
  1215. if (img_len > req_len) {
  1216. pkt_num = 0;
  1217. tmp_data[0] = FS_NO_MATCH;
  1218. pkt[pkt_num].len = sizeof(unsigned int);
  1219. pkt[pkt_num++].buf = (void *)&tmp_data[0];
  1220. /* set it as image length for modem ccci check when error happens */
  1221. pkt[pkt_num].len = img_len;
  1222. /* /pkt[pkt_num].len = sizeof(unsigned int); */
  1223. tmp_data[1] = img_len;
  1224. pkt[pkt_num++].buf = (void *)&tmp_data[1];
  1225. CCCI_ERR_MSG(md->index, RPC,
  1226. "RPC_GET_SECRO_OP: AP mis-match MD request length: (%d, %d)\n",
  1227. req_len, img_len);
  1228. break;
  1229. }
  1230. /* TODO : please check it */
  1231. /* save original modem secro length */
  1232. CCCI_DBG_MSG(md->index, RPC, "<rpc>RPC_GET_SECRO_OP: save MD SECRO length: (%d)\n",
  1233. img_len);
  1234. img_len_bak = img_len;
  1235. blk_sz = masp_secro_blk_sz();
  1236. for (cnt = 0; cnt < blk_sz; cnt++) {
  1237. tmp = tmp * 2;
  1238. if (tmp >= blk_sz)
  1239. break;
  1240. }
  1241. ++cnt;
  1242. img_len = ((img_len + (blk_sz - 1)) >> cnt) << cnt;
  1243. addr = (unsigned char *)&(p_rpc_buf->para_num) + 4 * sizeof(unsigned int);
  1244. tmp_data[0] = masp_secro_md_get_data(md->post_fix, addr, 0, img_len);
  1245. /* TODO : please check it */
  1246. /* restore original modem secro length */
  1247. img_len = img_len_bak;
  1248. CCCI_DBG_MSG(md->index, RPC, "<rpc>RPC_GET_SECRO_OP: restore MD SECRO length: (%d)\n",
  1249. img_len);
  1250. if (tmp_data[0] != 0) {
  1251. CCCI_ERR_MSG(md->index, RPC, "RPC_GET_SECRO_OP: get data fail:%d\n",
  1252. tmp_data[0]);
  1253. pkt_num = 0;
  1254. pkt[pkt_num].len = sizeof(unsigned int);
  1255. pkt[pkt_num++].buf = (void *)&tmp_data[0];
  1256. pkt[pkt_num].len = sizeof(unsigned int);
  1257. tmp_data[1] = img_len;
  1258. pkt[pkt_num++].buf = (void *)&tmp_data[1];
  1259. } else {
  1260. CCCI_DBG_MSG(md->index, RPC, "RPC_GET_SECRO_OP: get data OK: %d,%d\n", img_len,
  1261. tmp_data[0]);
  1262. pkt_num = 0;
  1263. pkt[pkt_num].len = sizeof(unsigned int);
  1264. /* pkt[pkt_num++].buf = (void*) &img_len; */
  1265. tmp_data[1] = img_len;
  1266. pkt[pkt_num++].buf = (void *)&tmp_data[1];
  1267. pkt[pkt_num].len = img_len;
  1268. pkt[pkt_num++].buf = (void *)addr;
  1269. /* tmp_data[2] = (unsigned int)addr; */
  1270. /* pkt[pkt_num++].buf = (void*) &tmp_data[2]; */
  1271. }
  1272. } else {
  1273. CCCI_DBG_MSG(md->index, RPC, "RPC_GET_SECRO_OP: secro disable\n");
  1274. tmp_data[0] = FS_NO_FEATURE;
  1275. pkt_num = 0;
  1276. pkt[pkt_num].len = sizeof(unsigned int);
  1277. pkt[pkt_num++].buf = (void *)&tmp_data[0];
  1278. pkt[pkt_num].len = sizeof(unsigned int);
  1279. tmp_data[1] = img_len;
  1280. pkt[pkt_num++].buf = (void *)&tmp_data[1];
  1281. }
  1282. break;
  1283. }
  1284. #endif
  1285. /* call EINT API to get TDD EINT configuration for modem EINT initial */
  1286. case IPC_RPC_GET_TDD_EINT_NUM_OP:
  1287. case IPC_RPC_GET_GPIO_NUM_OP:
  1288. case IPC_RPC_GET_ADC_NUM_OP:
  1289. {
  1290. int get_num = 0;
  1291. unsigned char *name = NULL;
  1292. unsigned int length = 0;
  1293. if (pkt_num < 2 || pkt_num > RPC_MAX_ARG_NUM) {
  1294. CCCI_ERR_MSG(md->index, RPC, "invalid parameter for [0x%X]: pkt_num=%d!\n",
  1295. p_rpc_buf->op_id, pkt_num);
  1296. tmp_data[0] = FS_PARAM_ERROR;
  1297. goto err1;
  1298. }
  1299. length = pkt[0].len;
  1300. if (length < 1) {
  1301. CCCI_ERR_MSG(md->index, RPC, "invalid parameter for [0x%X]: pkt_num=%d, name_len=%d!\n",
  1302. p_rpc_buf->op_id, pkt_num, length);
  1303. tmp_data[0] = FS_PARAM_ERROR;
  1304. goto err1;
  1305. }
  1306. name = kmalloc(length, GFP_KERNEL);
  1307. if (name == NULL) {
  1308. CCCI_ERR_MSG(md->index, RPC, "Fail alloc Mem for [0x%X]!\n", p_rpc_buf->op_id);
  1309. tmp_data[0] = FS_ERROR_RESERVED;
  1310. goto err1;
  1311. } else {
  1312. memcpy(name, (unsigned char *)(pkt[0].buf), length);
  1313. if (p_rpc_buf->op_id == IPC_RPC_GET_TDD_EINT_NUM_OP) {
  1314. get_num = get_td_eint_info(name, length);
  1315. if (get_num < 0)
  1316. get_num = FS_FUNC_FAIL;
  1317. } else if (p_rpc_buf->op_id == IPC_RPC_GET_GPIO_NUM_OP) {
  1318. get_num = get_md_gpio_info(name, length);
  1319. if (get_num < 0)
  1320. get_num = FS_FUNC_FAIL;
  1321. } else if (p_rpc_buf->op_id == IPC_RPC_GET_ADC_NUM_OP) {
  1322. get_num = get_md_adc_info(name, length);
  1323. if (get_num < 0)
  1324. get_num = FS_FUNC_FAIL;
  1325. }
  1326. CCCI_INF_MSG(md->index, RPC, "[0x%08X]: name:%s, len=%d, get_num:%d\n",
  1327. p_rpc_buf->op_id, name, length, get_num);
  1328. pkt_num = 0;
  1329. /* NOTE: tmp_data[1] not [0] */
  1330. tmp_data[1] = (unsigned int)get_num;
  1331. /* get_num may be invalid after exit this function */
  1332. pkt[pkt_num].len = sizeof(unsigned int);
  1333. pkt[pkt_num++].buf = (void *)(&tmp_data[1]);
  1334. pkt[pkt_num].len = sizeof(unsigned int);
  1335. pkt[pkt_num++].buf = (void *)(&tmp_data[1]);
  1336. kfree(name);
  1337. }
  1338. break;
  1339. err1:
  1340. pkt_num = 0;
  1341. pkt[pkt_num].len = sizeof(unsigned int);
  1342. pkt[pkt_num++].buf = (void *)&tmp_data[0];
  1343. pkt[pkt_num].len = sizeof(unsigned int);
  1344. pkt[pkt_num++].buf = (void *)&tmp_data[0];
  1345. break;
  1346. }
  1347. case IPC_RPC_GET_EMI_CLK_TYPE_OP:
  1348. {
  1349. int dram_type = 0;
  1350. int dram_clk = 0;
  1351. if (pkt_num != 0) {
  1352. CCCI_ERR_MSG(md->index, RPC, "invalid parameter for [0x%X]: pkt_num=%d!\n",
  1353. p_rpc_buf->op_id, pkt_num);
  1354. tmp_data[0] = FS_PARAM_ERROR;
  1355. goto err2;
  1356. }
  1357. if (get_dram_type_clk(&dram_clk, &dram_type)) {
  1358. tmp_data[0] = FS_FUNC_FAIL;
  1359. goto err2;
  1360. } else {
  1361. tmp_data[0] = 0;
  1362. CCCI_INF_MSG(md->index, RPC, "[0x%08X]: dram_clk: %d, dram_type:%d\n",
  1363. p_rpc_buf->op_id, dram_clk, dram_type);
  1364. }
  1365. tmp_data[1] = (unsigned int)dram_type;
  1366. tmp_data[2] = (unsigned int)dram_clk;
  1367. pkt_num = 0;
  1368. pkt[pkt_num].len = sizeof(unsigned int);
  1369. pkt[pkt_num++].buf = (void *)(&tmp_data[0]);
  1370. pkt[pkt_num].len = sizeof(unsigned int);
  1371. pkt[pkt_num++].buf = (void *)(&tmp_data[1]);
  1372. pkt[pkt_num].len = sizeof(unsigned int);
  1373. pkt[pkt_num++].buf = (void *)(&tmp_data[2]);
  1374. break;
  1375. err2:
  1376. pkt_num = 0;
  1377. pkt[pkt_num].len = sizeof(unsigned int);
  1378. pkt[pkt_num++].buf = (void *)&tmp_data[0];
  1379. pkt[pkt_num].len = sizeof(unsigned int);
  1380. pkt[pkt_num++].buf = (void *)&tmp_data[0];
  1381. pkt[pkt_num].len = sizeof(unsigned int);
  1382. pkt[pkt_num++].buf = (void *)&tmp_data[0];
  1383. break;
  1384. }
  1385. case IPC_RPC_GET_EINT_ATTR_OP:
  1386. {
  1387. char *eint_name = NULL;
  1388. unsigned int name_len = 0;
  1389. unsigned int type = 0;
  1390. char *res = NULL;
  1391. unsigned int res_len = 0;
  1392. int ret = 0;
  1393. if (pkt_num < 3 || pkt_num > RPC_MAX_ARG_NUM) {
  1394. CCCI_ERR_MSG(md->index, RPC, "invalid parameter for [0x%X]: pkt_num=%d!\n",
  1395. p_rpc_buf->op_id, pkt_num);
  1396. tmp_data[0] = FS_PARAM_ERROR;
  1397. goto err3;
  1398. }
  1399. name_len = pkt[0].len;
  1400. if (name_len < 1) {
  1401. CCCI_ERR_MSG(md->index, RPC, "invalid parameter for [0x%X]: pkt_num=%d, name_len=%d!\n",
  1402. p_rpc_buf->op_id, pkt_num, name_len);
  1403. tmp_data[0] = FS_PARAM_ERROR;
  1404. goto err3;
  1405. }
  1406. eint_name = kmalloc(name_len, GFP_KERNEL);
  1407. if (eint_name == NULL) {
  1408. CCCI_ERR_MSG(md->index, RPC, "Fail alloc Mem for [0x%X]!\n", p_rpc_buf->op_id);
  1409. tmp_data[0] = FS_ERROR_RESERVED;
  1410. goto err3;
  1411. } else {
  1412. memcpy(eint_name, (unsigned char *)(pkt[0].buf), name_len);
  1413. }
  1414. type = *(unsigned int *)(pkt[2].buf);
  1415. res = (unsigned char *)&(p_rpc_buf->para_num) + 4 * sizeof(unsigned int);
  1416. ret = get_eint_attr(eint_name, name_len, type, res, &res_len);
  1417. if (ret == 0) {
  1418. tmp_data[0] = ret;
  1419. pkt_num = 0;
  1420. pkt[pkt_num].len = sizeof(unsigned int);
  1421. pkt[pkt_num++].buf = (void *)&tmp_data[0];
  1422. pkt[pkt_num].len = res_len;
  1423. pkt[pkt_num++].buf = (void *)res;
  1424. CCCI_DBG_MSG(md->index, RPC,
  1425. "[0x%08X] OK: name:%s, len:%d, type:%d, res:%d, res_len:%d\n",
  1426. p_rpc_buf->op_id, eint_name, name_len, type, *res, res_len);
  1427. kfree(eint_name);
  1428. } else {
  1429. tmp_data[0] = ret;
  1430. CCCI_INF_MSG(md->index, RPC, "[0x%08X] fail: name:%s, len:%d, type:%d, ret:%d\n",
  1431. p_rpc_buf->op_id, eint_name, name_len, type, ret);
  1432. kfree(eint_name);
  1433. goto err3;
  1434. }
  1435. break;
  1436. err3:
  1437. pkt_num = 0;
  1438. pkt[pkt_num].len = sizeof(unsigned int);
  1439. pkt[pkt_num++].buf = (void *)&tmp_data[0];
  1440. pkt[pkt_num].len = sizeof(unsigned int);
  1441. pkt[pkt_num++].buf = (void *)&tmp_data[0];
  1442. break;
  1443. }
  1444. #ifdef FEATURE_RF_CLK_BUF
  1445. case IPC_RPC_GET_RF_CLK_BUF_OP:
  1446. {
  1447. u16 count = 0;
  1448. struct ccci_rpc_clkbuf_result *clkbuf;
  1449. CLK_BUF_SWCTRL_STATUS_T swctrl_status[CLKBUF_MAX_COUNT];
  1450. if (pkt_num != 1) {
  1451. CCCI_ERR_MSG(md->index, RPC, "invalid parameter for [0x%X]: pkt_num=%d!\n",
  1452. p_rpc_buf->op_id, pkt_num);
  1453. tmp_data[0] = FS_PARAM_ERROR;
  1454. pkt_num = 0;
  1455. pkt[pkt_num].len = sizeof(unsigned int);
  1456. pkt[pkt_num++].buf = (void *)&tmp_data[0];
  1457. pkt[pkt_num].len = sizeof(unsigned int);
  1458. pkt[pkt_num++].buf = (void *)&tmp_data[0];
  1459. break;
  1460. }
  1461. count = *(u16 *) (pkt[0].buf);
  1462. pkt_num = 0;
  1463. tmp_data[0] = 0;
  1464. pkt[pkt_num].len = sizeof(unsigned int);
  1465. pkt[pkt_num++].buf = (void *)&tmp_data[0];
  1466. pkt[pkt_num].len = sizeof(struct ccci_rpc_clkbuf_result);
  1467. pkt[pkt_num++].buf = (void *)&tmp_data[1];
  1468. clkbuf = (struct ccci_rpc_clkbuf_result *)&tmp_data[1];
  1469. if (count != CLKBUF_MAX_COUNT) {
  1470. CCCI_ERR_MSG(md->index, RPC, "IPC_RPC_GET_RF_CLK_BUF, wrong count %d/%d\n", count,
  1471. CLKBUF_MAX_COUNT);
  1472. clkbuf->CLKBuf_Count = 0xFF;
  1473. memset(&clkbuf->CLKBuf_Status, 0, sizeof(clkbuf->CLKBuf_Status));
  1474. } else {
  1475. #if !defined(CONFIG_MTK_LEGACY)
  1476. struct device_node *node;
  1477. u32 vals[4] = {0, 0, 0, 0};
  1478. node = of_find_compatible_node(NULL, NULL, "mediatek,rf_clock_buffer");
  1479. if (node) {
  1480. of_property_read_u32_array(node, "mediatek,clkbuf-config", vals, 4);
  1481. } else {
  1482. CCCI_ERR_MSG(md->index, RPC, "%s can't find compatible node\n", __func__);
  1483. }
  1484. #else
  1485. u32 vals[4] = {CLK_BUF1_STATUS, CLK_BUF2_STATUS, CLK_BUF3_STATUS, CLK_BUF4_STATUS};
  1486. #endif
  1487. clkbuf->CLKBuf_Count = CLKBUF_MAX_COUNT;
  1488. clkbuf->CLKBuf_Status[0] = vals[0];
  1489. clkbuf->CLKBuf_Status[1] = vals[1];
  1490. clkbuf->CLKBuf_Status[2] = vals[2];
  1491. clkbuf->CLKBuf_Status[3] = vals[3];
  1492. clk_buf_get_swctrl_status(swctrl_status);
  1493. clkbuf->CLKBuf_SWCtrl_Status[0] = swctrl_status[0];
  1494. clkbuf->CLKBuf_SWCtrl_Status[1] = swctrl_status[1];
  1495. clkbuf->CLKBuf_SWCtrl_Status[2] = swctrl_status[2];
  1496. clkbuf->CLKBuf_SWCtrl_Status[3] = swctrl_status[3];
  1497. }
  1498. CCCI_DBG_MSG(md->index, RPC, "IPC_RPC_GET_RF_CLK_BUF count=%x\n", clkbuf->CLKBuf_Count);
  1499. break;
  1500. }
  1501. #endif
  1502. case IPC_RPC_GET_GPIO_VAL_OP:
  1503. case IPC_RPC_GET_ADC_VAL_OP:
  1504. {
  1505. unsigned int num = 0;
  1506. int val = 0;
  1507. if (pkt_num != 1) {
  1508. CCCI_ERR_MSG(md->index, RPC, "invalid parameter for [0x%X]: pkt_num=%d!\n",
  1509. p_rpc_buf->op_id, pkt_num);
  1510. tmp_data[0] = FS_PARAM_ERROR;
  1511. goto err4;
  1512. }
  1513. num = *(unsigned int *)(pkt[0].buf);
  1514. if (p_rpc_buf->op_id == IPC_RPC_GET_GPIO_VAL_OP)
  1515. val = get_md_gpio_val(num);
  1516. else if (p_rpc_buf->op_id == IPC_RPC_GET_ADC_VAL_OP)
  1517. val = get_md_adc_val(num);
  1518. tmp_data[0] = val;
  1519. CCCI_DBG_MSG(md->index, RPC, "[0x%X]: num=%d, val=%d!\n", p_rpc_buf->op_id, num, val);
  1520. err4:
  1521. pkt_num = 0;
  1522. pkt[pkt_num].len = sizeof(unsigned int);
  1523. pkt[pkt_num++].buf = (void *)&tmp_data[0];
  1524. pkt[pkt_num].len = sizeof(unsigned int);
  1525. pkt[pkt_num++].buf = (void *)&tmp_data[0];
  1526. break;
  1527. }
  1528. case IPC_RPC_GET_GPIO_ADC_OP:
  1529. {
  1530. struct ccci_rpc_gpio_adc_intput *input;
  1531. struct ccci_rpc_gpio_adc_output *output;
  1532. struct ccci_rpc_gpio_adc_intput_v2 *input_v2;
  1533. struct ccci_rpc_gpio_adc_output_v2 *output_v2;
  1534. unsigned int pkt_size;
  1535. if (pkt_num != 1) {
  1536. CCCI_ERR_MSG(md->index, RPC, "invalid parameter for [0x%X]: pkt_num=%d!\n",
  1537. p_rpc_buf->op_id, pkt_num);
  1538. tmp_data[0] = FS_PARAM_ERROR;
  1539. pkt_num = 0;
  1540. pkt[pkt_num].len = sizeof(unsigned int);
  1541. pkt[pkt_num++].buf = (void *)&tmp_data[0];
  1542. pkt[pkt_num].len = sizeof(unsigned int);
  1543. pkt[pkt_num++].buf = (void *)&tmp_data[0];
  1544. break;
  1545. }
  1546. pkt_size = pkt[0].len;
  1547. if (pkt_size == sizeof(struct ccci_rpc_gpio_adc_intput)) {
  1548. input = (struct ccci_rpc_gpio_adc_intput *)(pkt[0].buf);
  1549. pkt_num = 0;
  1550. tmp_data[0] = 0;
  1551. pkt[pkt_num].len = sizeof(unsigned int);
  1552. pkt[pkt_num++].buf = (void *)&tmp_data[0];
  1553. pkt[pkt_num].len = sizeof(struct ccci_rpc_gpio_adc_output);
  1554. pkt[pkt_num++].buf = (void *)&tmp_data[1];
  1555. output = (struct ccci_rpc_gpio_adc_output *)&tmp_data[1];
  1556. memset(output, 0xF, sizeof(struct ccci_rpc_gpio_adc_output)); /* 0xF for failure */
  1557. CCCI_DBG_MSG(md->index, KERN, "IPC_RPC_GET_GPIO_ADC_OP request=%x\n", input->reqMask);
  1558. ccci_rpc_get_gpio_adc(input, output);
  1559. } else if (pkt_size == sizeof(struct ccci_rpc_gpio_adc_intput_v2)) {
  1560. input_v2 = (struct ccci_rpc_gpio_adc_intput_v2 *)(pkt[0].buf);
  1561. pkt_num = 0;
  1562. tmp_data[0] = 0;
  1563. pkt[pkt_num].len = sizeof(unsigned int);
  1564. pkt[pkt_num++].buf = (void *)&tmp_data[0];
  1565. pkt[pkt_num].len = sizeof(struct ccci_rpc_gpio_adc_output_v2);
  1566. pkt[pkt_num++].buf = (void *)&tmp_data[1];
  1567. output_v2 = (struct ccci_rpc_gpio_adc_output_v2 *)&tmp_data[1];
  1568. /* 0xF for failure */
  1569. memset(output_v2, 0xF, sizeof(struct ccci_rpc_gpio_adc_output_v2));
  1570. CCCI_INF_MSG(md->index, KERN, "IPC_RPC_GET_GPIO_ADC_OP request=%x\n",
  1571. input_v2->reqMask);
  1572. ccci_rpc_get_gpio_adc_v2(input_v2, output_v2);
  1573. } else {
  1574. CCCI_ERR_MSG(md->index, RPC, "can't recognize pkt size%d!\n", pkt_size);
  1575. tmp_data[0] = FS_PARAM_ERROR;
  1576. pkt_num = 0;
  1577. pkt[pkt_num].len = sizeof(unsigned int);
  1578. pkt[pkt_num++].buf = (void *)&tmp_data[0];
  1579. pkt[pkt_num].len = sizeof(unsigned int);
  1580. pkt[pkt_num++].buf = (void *)&tmp_data[0];
  1581. }
  1582. break;
  1583. }
  1584. case IPC_RPC_DSP_EMI_MPU_SETTING:
  1585. {
  1586. struct ccci_rpc_dsp_emi_mpu_input *input, *output;
  1587. if (pkt_num != 1) {
  1588. CCCI_ERR_MSG(md->index, RPC, "invalid parameter for [0x%X]: pkt_num=%d!\n",
  1589. p_rpc_buf->op_id, pkt_num);
  1590. tmp_data[0] = FS_PARAM_ERROR;
  1591. pkt_num = 0;
  1592. pkt[pkt_num].len = sizeof(unsigned int);
  1593. pkt[pkt_num++].buf = (void *)&tmp_data[0];
  1594. pkt[pkt_num].len = sizeof(unsigned int);
  1595. pkt[pkt_num++].buf = (void *)&tmp_data[0];
  1596. break;
  1597. }
  1598. input = (struct ccci_rpc_dsp_emi_mpu_input *)(pkt[0].buf);
  1599. pkt_num = 0;
  1600. tmp_data[0] = 0;
  1601. pkt[pkt_num].len = sizeof(unsigned int);
  1602. pkt[pkt_num++].buf = (void *)&tmp_data[0];
  1603. pkt[pkt_num].len = sizeof(struct ccci_rpc_dsp_emi_mpu_input);
  1604. pkt[pkt_num++].buf = (void *)&tmp_data[1];
  1605. output = (struct ccci_rpc_dsp_emi_mpu_input *)&tmp_data[1];
  1606. output->request = 0;
  1607. CCCI_INF_MSG(md->index, KERN, "IPC_RPC_DSP_EMI_MPU_SETTING request=%x\n", input->request);
  1608. if (md->mem_layout.dsp_region_phy != 0)
  1609. ccci_set_dsp_region_protection(md, 1);
  1610. break;
  1611. }
  1612. #ifdef FEATURE_INFORM_NFC_VSIM_CHANGE
  1613. case IPC_RPC_USIM2NFC_OP:
  1614. {
  1615. struct ccci_rpc_usim2nfs *input, *output;
  1616. if (pkt_num != 1) {
  1617. CCCI_ERR_MSG(md->index, RPC, "invalid parameter for [0x%X]: pkt_num=%d!\n",
  1618. p_rpc_buf->op_id, pkt_num);
  1619. tmp_data[0] = FS_PARAM_ERROR;
  1620. pkt_num = 0;
  1621. pkt[pkt_num].len = sizeof(unsigned int);
  1622. pkt[pkt_num++].buf = (void *)&tmp_data[0];
  1623. pkt[pkt_num].len = sizeof(unsigned int);
  1624. pkt[pkt_num++].buf = (void *)&tmp_data[0];
  1625. break;
  1626. }
  1627. input = (struct ccci_rpc_usim2nfs *)(pkt[0].buf);
  1628. pkt_num = 0;
  1629. tmp_data[0] = 0;
  1630. pkt[pkt_num].len = sizeof(unsigned int);
  1631. pkt[pkt_num++].buf = (void *)&tmp_data[0];
  1632. pkt[pkt_num].len = sizeof(struct ccci_rpc_usim2nfs);
  1633. pkt[pkt_num++].buf = (void *)&tmp_data[1];
  1634. output = (struct ccci_rpc_usim2nfs *)&tmp_data[1];
  1635. output->lock_vsim1 = input->lock_vsim1;
  1636. CCCI_DBG_MSG(md->index, KERN, "IPC_RPC_USIM2NFC_OP request=%x\n", input->lock_vsim1);
  1637. /* lock_vsim1==1, NFC not power VSIM; lock_vsim==0, NFC power VSIM */
  1638. inform_nfc_vsim_change(md->index, 1, input->lock_vsim1);
  1639. break;
  1640. }
  1641. #endif
  1642. case IPC_RPC_IT_OP:
  1643. {
  1644. int i;
  1645. CCCI_INF_MSG(md->index, RPC, "[RPCIT] enter IT operation in ccci_rpc_work\n");
  1646. /* exam input parameters in pkt */
  1647. for (i = 0; i < pkt_num; i++) {
  1648. CCCI_INF_MSG(md->index, RPC, "len=%d val=%X\n", pkt[i].len,
  1649. *((unsigned int *)pkt[i].buf));
  1650. }
  1651. tmp_data[0] = 1;
  1652. tmp_data[1] = 0xA5A5;
  1653. pkt_num = 0;
  1654. CCCI_INF_MSG(md->index, RPC, "[RPCIT] prepare output parameters\n");
  1655. pkt[pkt_num].len = sizeof(unsigned int);
  1656. pkt[pkt_num++].buf = (void *)&tmp_data[0];
  1657. CCCI_INF_MSG(md->index, RPC, "[RPCIT] LV[%d] len= 0x%08X, value= 0x%08X\n", 0, pkt[0].len,
  1658. *((unsigned int *)pkt[0].buf));
  1659. pkt[pkt_num].len = sizeof(unsigned int);
  1660. pkt[pkt_num++].buf = (void *)&tmp_data[1];
  1661. CCCI_INF_MSG(md->index, RPC, "[RPCIT] LV[%d] len= 0x%08X, value= 0x%08X\n", 1, pkt[1].len,
  1662. *((unsigned int *)pkt[1].buf));
  1663. break;
  1664. }
  1665. default:
  1666. CCCI_INF_MSG(md->index, RPC, "[Error]Unknown Operation ID (0x%08X)\n", p_rpc_buf->op_id);
  1667. tmp_data[0] = FS_NO_OP;
  1668. pkt_num = 0;
  1669. pkt[pkt_num].len = sizeof(int);
  1670. pkt[pkt_num++].buf = (void *)&tmp_data[0];
  1671. break;
  1672. }
  1673. p_rpc_buf->para_num = pkt_num;
  1674. CCCI_DBG_MSG(md->index, RPC, "ccci_rpc_work_helper-- %d\n", p_rpc_buf->para_num);
  1675. }
  1676. static void rpc_msg_handler(struct ccci_port *port, struct ccci_request *req)
  1677. {
  1678. struct ccci_modem *md = port->modem;
  1679. struct rpc_buffer *rpc_buf = (struct rpc_buffer *)req->skb->data;
  1680. int i, data_len = 0, AlignLength, ret;
  1681. struct rpc_pkt pkt[RPC_MAX_ARG_NUM];
  1682. char *ptr, *ptr_base;
  1683. /* unsigned int tmp_data[128]; */ /* size of tmp_data should be >= any RPC output result */
  1684. unsigned int *tmp_data = kmalloc(128*sizeof(unsigned int), GFP_ATOMIC);
  1685. if (tmp_data == NULL) {
  1686. CCCI_ERR_MSG(md->index, RPC, "RPC request buffer fail 128*sizeof(unsigned int)\n");
  1687. goto err_out;
  1688. }
  1689. /* sanity check */
  1690. if (rpc_buf->header.reserved < 0 || rpc_buf->header.reserved > RPC_REQ_BUFFER_NUM ||
  1691. rpc_buf->para_num < 0 || rpc_buf->para_num > RPC_MAX_ARG_NUM) {
  1692. CCCI_ERR_MSG(md->index, RPC, "invalid RPC index %d/%d\n", rpc_buf->header.reserved, rpc_buf->para_num);
  1693. goto err_out;
  1694. }
  1695. /* parse buffer */
  1696. ptr_base = ptr = rpc_buf->buffer;
  1697. for (i = 0; i < rpc_buf->para_num; i++) {
  1698. pkt[i].len = *((unsigned int *)ptr);
  1699. ptr += sizeof(pkt[i].len);
  1700. pkt[i].buf = ptr;
  1701. ptr += ((pkt[i].len + 3) >> 2) << 2; /* 4byte align */
  1702. }
  1703. if ((ptr - ptr_base) > RPC_MAX_BUF_SIZE) {
  1704. CCCI_ERR_MSG(md->index, RPC, "RPC overflow in parse 0x%p\n", (void *)(ptr - ptr_base));
  1705. goto err_out;
  1706. }
  1707. /* handle RPC request */
  1708. ccci_rpc_work_helper(md, pkt, rpc_buf, tmp_data);
  1709. /* write back to modem */
  1710. /* update message */
  1711. rpc_buf->op_id |= RPC_API_RESP_ID;
  1712. data_len += (sizeof(rpc_buf->op_id) + sizeof(rpc_buf->para_num));
  1713. ptr = rpc_buf->buffer;
  1714. for (i = 0; i < rpc_buf->para_num; i++) {
  1715. if ((data_len + sizeof(pkt[i].len) + pkt[i].len) > RPC_MAX_BUF_SIZE) {
  1716. CCCI_ERR_MSG(md->index, RPC, "RPC overflow in write %zu\n",
  1717. data_len + sizeof(pkt[i].len) + pkt[i].len);
  1718. goto err_out;
  1719. }
  1720. *((unsigned int *)ptr) = pkt[i].len;
  1721. ptr += sizeof(pkt[i].len);
  1722. data_len += sizeof(pkt[i].len);
  1723. AlignLength = ((pkt[i].len + 3) >> 2) << 2; /* 4byte aligned */
  1724. data_len += AlignLength;
  1725. if (ptr != pkt[i].buf)
  1726. memcpy(ptr, pkt[i].buf, pkt[i].len);
  1727. else
  1728. CCCI_DBG_MSG(md->index, RPC, "same addr, no copy, op_id=0x%x\n", rpc_buf->op_id);
  1729. ptr += AlignLength;
  1730. }
  1731. /* resize skb */
  1732. data_len += sizeof(struct ccci_header);
  1733. if (data_len > req->skb->len)
  1734. skb_put(req->skb, data_len - req->skb->len);
  1735. else if (data_len < req->skb->len)
  1736. skb_trim(req->skb, data_len);
  1737. /* update CCCI header */
  1738. rpc_buf->header.channel = CCCI_RPC_TX;
  1739. rpc_buf->header.data[1] = data_len;
  1740. CCCI_DBG_MSG(md->index, RPC, "Write %d/%d, %08X, %08X, %08X, %08X, op_id=0x%x\n", req->skb->len, data_len,
  1741. rpc_buf->header.data[0], rpc_buf->header.data[1], rpc_buf->header.channel,
  1742. rpc_buf->header.reserved, rpc_buf->op_id);
  1743. /* switch to Tx request */
  1744. req->policy = RECYCLE;
  1745. req->blocking = 1;
  1746. ret = ccci_port_send_request(port, req);
  1747. if (ret)
  1748. goto err_out;
  1749. kfree(tmp_data);
  1750. return;
  1751. err_out:
  1752. kfree(tmp_data);
  1753. req->policy = RECYCLE;
  1754. ccci_free_req(req);
  1755. }
  1756. static void status_msg_handler(struct ccci_port *port, struct ccci_request *req)
  1757. {
  1758. struct ccci_modem *md = port->modem;
  1759. struct ccci_header *ccci_h = (struct ccci_header *)req->skb->data;
  1760. del_timer(&port->modem->md_status_timeout);
  1761. CCCI_INF_MSG(port->modem->index, KERN, "modem status info seq=0x%X\n", *(((u32 *) ccci_h) + 2));
  1762. ccci_cmpt_mem_dump(md->index, req->skb->data, req->skb->len);
  1763. req->policy = RECYCLE;
  1764. ccci_free_req(req);
  1765. if (port->modem->md_state == READY)
  1766. mod_timer(&port->modem->md_status_poller, jiffies + 15 * HZ);
  1767. }
  1768. void md_status_poller_func(unsigned long data)
  1769. {
  1770. struct ccci_modem *md = (struct ccci_modem *)data;
  1771. int ret;
  1772. mod_timer(&md->md_status_timeout, jiffies + 5 * HZ);
  1773. ret = ccci_send_msg_to_md(md, CCCI_STATUS_TX, 0, 0, 0);
  1774. CCCI_INF_MSG(md->index, KERN, "poll modem status %d seq=0x%X\n", ret, md->seq_nums[OUT][CCCI_STATUS_TX]);
  1775. if (ret) {
  1776. CCCI_ERR_MSG(md->index, KERN, "fail to send modem status polling msg ret=%d\n", ret);
  1777. del_timer(&md->md_status_timeout);
  1778. if ((ret == -EBUSY || (ret == -CCCI_ERR_ALLOCATE_MEMORY_FAIL)) && md->md_state == READY) {
  1779. if (md->md_status_poller_flag & MD_STATUS_POLL_BUSY) {
  1780. md->ops->dump_info(md, DUMP_FLAG_QUEUE_0, NULL, 0);
  1781. ccci_md_exception_notify(md, MD_NO_RESPONSE);
  1782. } else if (ret == -CCCI_ERR_ALLOCATE_MEMORY_FAIL) {
  1783. mod_timer(&md->md_status_poller, jiffies + 10 * HZ);
  1784. } else {
  1785. md->md_status_poller_flag |= MD_STATUS_POLL_BUSY;
  1786. mod_timer(&md->md_status_poller, jiffies + 10 * HZ);
  1787. }
  1788. }
  1789. } else {
  1790. md->md_status_poller_flag &= ~MD_STATUS_POLL_BUSY;
  1791. }
  1792. }
  1793. void md_status_timeout_func(unsigned long data)
  1794. {
  1795. struct ccci_modem *md = (struct ccci_modem *)data;
  1796. if (md->md_status_poller_flag & MD_STATUS_ASSERTED) {
  1797. CCCI_ERR_MSG(md->index, KERN, "modem status polling timeout, assert fail\n");
  1798. ccci_md_exception_notify(md, MD_NO_RESPONSE);
  1799. } else {
  1800. CCCI_ERR_MSG(md->index, KERN, "modem status polling timeout, force assert\n");
  1801. md->md_status_poller_flag |= MD_STATUS_ASSERTED;
  1802. md->ops->dump_info(md, DUMP_FLAG_QUEUE_0, NULL, 0);
  1803. mod_timer(&md->md_status_timeout, jiffies + 5 * HZ);
  1804. md->ops->force_assert(md, CCIF_INTR_SEQ);
  1805. }
  1806. }
  1807. static int port_kernel_thread(void *arg)
  1808. {
  1809. struct ccci_port *port = arg;
  1810. /* struct sched_param param = { .sched_priority = 1 }; */
  1811. struct ccci_request *req;
  1812. struct ccci_header *ccci_h;
  1813. unsigned long flags;
  1814. int ret;
  1815. CCCI_DBG_MSG(port->modem->index, KERN, "port %s's thread running\n", port->name);
  1816. /* sched_setscheduler(current, SCHED_FIFO, &param); */
  1817. while (1) {
  1818. if (list_empty(&port->rx_req_list)) {
  1819. ret = wait_event_interruptible(port->rx_wq, !list_empty(&port->rx_req_list));
  1820. if (ret == -ERESTARTSYS)
  1821. continue; /* FIXME */
  1822. }
  1823. if (kthread_should_stop())
  1824. break;
  1825. CCCI_DBG_MSG(port->modem->index, KERN, "read on %s\n", port->name);
  1826. /* 1. dequeue */
  1827. spin_lock_irqsave(&port->rx_req_lock, flags);
  1828. req = list_first_entry(&port->rx_req_list, struct ccci_request, entry);
  1829. list_del(&req->entry);
  1830. if (--(port->rx_length) == 0)
  1831. ccci_port_ask_more_request(port);
  1832. spin_unlock_irqrestore(&port->rx_req_lock, flags);
  1833. /* 2. process the request */
  1834. ccci_h = (struct ccci_header *)req->skb->data;
  1835. switch (ccci_h->channel) { /* for a certain thread, only one kind of message is handled */
  1836. case CCCI_CONTROL_RX:
  1837. control_msg_handler(port, req);
  1838. break;
  1839. case CCCI_SYSTEM_RX:
  1840. system_msg_handler(port, req);
  1841. break;
  1842. case CCCI_RPC_RX:
  1843. rpc_msg_handler(port, req);
  1844. CCCI_DBG_MSG(port->modem->index, KERN, "rpc done %s\n", port->name);
  1845. break;
  1846. case CCCI_STATUS_RX:
  1847. status_msg_handler(port, req);
  1848. break;
  1849. };
  1850. /* ATTENTION, message handler will free request, do NOT reference request any more */
  1851. }
  1852. return 0;
  1853. }
  1854. int port_kernel_init(struct ccci_port *port)
  1855. {
  1856. CCCI_DBG_MSG(port->modem->index, KERN, "kernel port %s is initializing\n", port->name);
  1857. port->private_data = kthread_run(port_kernel_thread, port, "%s", port->name);
  1858. port->rx_length_th = MAX_QUEUE_LENGTH;
  1859. return 0;
  1860. }
  1861. int port_kernel_recv_req(struct ccci_port *port, struct ccci_request *req)
  1862. {
  1863. unsigned long flags;
  1864. spin_lock_irqsave(&port->rx_req_lock, flags);
  1865. CCCI_DBG_MSG(port->modem->index, IPC, "recv on %s, len=%d\n", port->name, port->rx_length);
  1866. if (port->rx_length < port->rx_length_th) {
  1867. port->flags &= ~PORT_F_RX_FULLED;
  1868. port->rx_length++;
  1869. list_del(&req->entry); /* dequeue from queue's list */
  1870. list_add_tail(&req->entry, &port->rx_req_list);
  1871. spin_unlock_irqrestore(&port->rx_req_lock, flags);
  1872. wake_lock_timeout(&port->rx_wakelock, HZ);
  1873. wake_up_all(&port->rx_wq);
  1874. return 0;
  1875. }
  1876. port->flags |= PORT_F_RX_FULLED;
  1877. spin_unlock_irqrestore(&port->rx_req_lock, flags);
  1878. if (port->flags & PORT_F_ALLOW_DROP/* || !(port->flags&PORT_F_RX_EXCLUSIVE) */) {
  1879. CCCI_INF_MSG(port->modem->index, KERN, "port %s Rx full, drop packet\n", port->name);
  1880. goto drop;
  1881. } else {
  1882. return -CCCI_ERR_PORT_RX_FULL;
  1883. }
  1884. drop:
  1885. /* drop this packet */
  1886. CCCI_INF_MSG(port->modem->index, KERN, "drop on %s, len=%d\n", port->name, port->rx_length);
  1887. list_del(&req->entry);
  1888. req->policy = RECYCLE;
  1889. ccci_free_req(req);
  1890. return -CCCI_ERR_DROP_PACKET;
  1891. }
  1892. int port_kernel_req_match(struct ccci_port *port, struct ccci_request *req)
  1893. {
  1894. struct ccci_header *ccci_h = (struct ccci_header *)req->skb->data;
  1895. struct rpc_buffer *rpc_buf;
  1896. if (ccci_h->channel == CCCI_RPC_RX) {
  1897. rpc_buf = (struct rpc_buffer *)req->skb->data;
  1898. switch (rpc_buf->op_id) {
  1899. #ifdef CONFIG_MTK_TC1_FEATURE
  1900. /* LGE specific OP ID */
  1901. case RPC_CCCI_LGE_FAC_READ_SIM_LOCK_TYPE:
  1902. case RPC_CCCI_LGE_FAC_READ_FUSG_FLAG:
  1903. case RPC_CCCI_LGE_FAC_CHECK_UNLOCK_CODE_VALIDNESS:
  1904. case RPC_CCCI_LGE_FAC_CHECK_NETWORK_CODE_VALIDNESS:
  1905. case RPC_CCCI_LGE_FAC_WRITE_SIM_LOCK_TYPE:
  1906. case RPC_CCCI_LGE_FAC_READ_IMEI:
  1907. case RPC_CCCI_LGE_FAC_WRITE_IMEI:
  1908. case RPC_CCCI_LGE_FAC_READ_NETWORK_CODE_LIST_NUM:
  1909. case RPC_CCCI_LGE_FAC_READ_NETWORK_CODE:
  1910. case RPC_CCCI_LGE_FAC_WRITE_NETWORK_CODE_LIST_NUM:
  1911. case RPC_CCCI_LGE_FAC_WRITE_UNLOCK_CODE_VERIFY_FAIL_COUNT:
  1912. case RPC_CCCI_LGE_FAC_READ_UNLOCK_CODE_VERIFY_FAIL_COUNT:
  1913. case RPC_CCCI_LGE_FAC_WRITE_UNLOCK_FAIL_COUNT:
  1914. case RPC_CCCI_LGE_FAC_READ_UNLOCK_FAIL_COUNT:
  1915. case RPC_CCCI_LGE_FAC_WRITE_UNLOCK_CODE:
  1916. case RPC_CCCI_LGE_FAC_VERIFY_UNLOCK_CODE:
  1917. case RPC_CCCI_LGE_FAC_WRITE_NETWORK_CODE:
  1918. case RPC_CCCI_LGE_FAC_INIT_SIM_LOCK_DATA:
  1919. CCCI_DBG_MSG(port->modem->index, KERN, "userspace rpc msg 0x%x on %s\n",
  1920. rpc_buf->op_id, port->name);
  1921. return 0;
  1922. #endif
  1923. default:
  1924. CCCI_DBG_MSG(port->modem->index, KERN, "kernelspace rpc msg 0x%x on %s\n",
  1925. rpc_buf->op_id, port->name);
  1926. return 1;
  1927. }
  1928. }
  1929. /*default all port_kernell return 1*/
  1930. return 1;
  1931. }
  1932. static void port_kernel_md_state_notice(struct ccci_port *port, MD_STATE state)
  1933. {
  1934. if (port->rx_ch != CCCI_CONTROL_RX)
  1935. return;
  1936. /* only for thoes states which are updated by modem driver */
  1937. switch (state) {
  1938. case RESET:
  1939. del_timer(&port->modem->md_status_poller);
  1940. del_timer(&port->modem->md_status_timeout);
  1941. del_timer(&port->modem->ex_monitor);
  1942. del_timer(&port->modem->ex_monitor2);
  1943. port->modem->md_status_poller_flag = 0;
  1944. break;
  1945. default:
  1946. break;
  1947. };
  1948. }
  1949. struct ccci_port_ops kernel_port_ops = {
  1950. .init = &port_kernel_init,
  1951. .req_match = &port_kernel_req_match,
  1952. .recv_request = &port_kernel_recv_req,
  1953. .md_state_notice = &port_kernel_md_state_notice,
  1954. };
  1955. void ccci_md_exception_notify(struct ccci_modem *md, MD_EX_STAGE stage)
  1956. {
  1957. unsigned long flags;
  1958. spin_lock_irqsave(&md->ctrl_lock, flags);
  1959. CCCI_NOTICE_MSG(md->index, KERN, "MD exception logical %d->%d\n", md->ex_stage, stage);
  1960. md->ex_stage = stage;
  1961. switch (md->ex_stage) {
  1962. case EX_INIT:
  1963. del_timer(&md->ex_monitor2);
  1964. del_timer(&md->bootup_timer);
  1965. del_timer(&md->md_status_poller);
  1966. del_timer(&md->md_status_timeout);
  1967. md->ee_info_flag |= ((1 << MD_EE_FLOW_START) | (1 << MD_EE_SWINT_GET));
  1968. md->ops->broadcast_state(md, EXCEPTION);
  1969. break;
  1970. case EX_DHL_DL_RDY:
  1971. break;
  1972. case EX_INIT_DONE:
  1973. if (!MD_IN_DEBUG(md))
  1974. mod_timer(&md->ex_monitor, jiffies + EX_TIMER_SWINT * HZ);
  1975. ccci_reset_seq_num(md);
  1976. break;
  1977. case MD_NO_RESPONSE:
  1978. /* don't broadcast exception state, only dump */
  1979. del_timer(&md->md_status_timeout);
  1980. CCCI_ERR_MSG(md->index, KERN, "MD long time no response, flag=%x\n", md->md_status_poller_flag);
  1981. md->ee_info_flag |= ((1 << MD_EE_FLOW_START) | (1 << MD_EE_PENDING_TOO_LONG) | (1 << MD_STATE_UPDATE));
  1982. mod_timer(&md->ex_monitor, jiffies);
  1983. break;
  1984. case MD_WDT:
  1985. del_timer(&md->md_status_poller);
  1986. del_timer(&md->md_status_timeout);
  1987. md->ee_info_flag |= ((1 << MD_EE_FLOW_START) | (1 << MD_EE_WDT_GET) | (1 << MD_STATE_UPDATE));
  1988. mod_timer(&md->ex_monitor, jiffies);
  1989. break;
  1990. default:
  1991. break;
  1992. };
  1993. spin_unlock_irqrestore(&md->ctrl_lock, flags);
  1994. }
  1995. EXPORT_SYMBOL(ccci_md_exception_notify);
  1996. static void ccci_aed(struct ccci_modem *md, unsigned int dump_flag, char *aed_str, int db_opt)
  1997. {
  1998. void *ex_log_addr = NULL;
  1999. int ex_log_len = 0;
  2000. void *md_img_addr = NULL;
  2001. int md_img_len = 0;
  2002. int info_str_len = 0;
  2003. char *buff; /*[AED_STR_LEN]; */
  2004. char *img_inf;
  2005. buff = kmalloc(AED_STR_LEN, GFP_ATOMIC);
  2006. if (buff == NULL) {
  2007. CCCI_EXP_MSG(md->index, KERN, "Fail alloc Mem for buff!\n");
  2008. goto err_exit1;
  2009. }
  2010. img_inf = ccci_get_md_info_str(md->index);
  2011. if (img_inf == NULL)
  2012. img_inf = "";
  2013. info_str_len = strlen(aed_str);
  2014. info_str_len += strlen(img_inf);
  2015. if (info_str_len > AED_STR_LEN)
  2016. buff[AED_STR_LEN - 1] = '\0'; /* Cut string length to AED_STR_LEN */
  2017. snprintf(buff, AED_STR_LEN, "md%d:%s%s", md->index + 1, aed_str, img_inf);
  2018. /* MD ID must sync with aee_dump_ccci_debug_info() */
  2019. err_exit1:
  2020. if (dump_flag & CCCI_AED_DUMP_CCIF_REG) { /* check this first, as we overwrite share memory here */
  2021. ex_log_addr = md->smem_layout.ccci_exp_smem_mdss_debug_vir;
  2022. ex_log_len = md->smem_layout.ccci_exp_smem_mdss_debug_size;
  2023. md->ops->dump_info(md, DUMP_FLAG_CCIF | DUMP_FLAG_CCIF_REG,
  2024. md->smem_layout.ccci_exp_smem_base_vir + CCCI_SMEM_OFFSET_CCIF_SRAM,
  2025. CCCC_SMEM_CCIF_SRAM_SIZE);
  2026. }
  2027. if (dump_flag & CCCI_AED_DUMP_EX_MEM) {
  2028. ex_log_addr = md->smem_layout.ccci_exp_smem_mdss_debug_vir;
  2029. ex_log_len = md->smem_layout.ccci_exp_smem_mdss_debug_size;
  2030. }
  2031. if (dump_flag & CCCI_AED_DUMP_EX_PKT) {
  2032. #ifdef MD_UMOLY_EE_SUPPORT
  2033. if (md->index == MD_SYS1) {
  2034. ex_log_addr = (void *)md->ex_pl_info;
  2035. ex_log_len = MD_HS1_FAIL_DUMP_SIZE/*sizeof(EX_PL_LOG_T)*/;
  2036. } else {
  2037. #endif
  2038. ex_log_addr = (void *)&md->ex_info;
  2039. ex_log_len = sizeof(EX_LOG_T);
  2040. #ifdef MD_UMOLY_EE_SUPPORT
  2041. }
  2042. #endif
  2043. }
  2044. if (dump_flag & CCCI_AED_DUMP_MD_IMG_MEM) {
  2045. md_img_addr = (void *)md->mem_layout.md_region_vir;
  2046. md_img_len = MD_IMG_DUMP_SIZE;
  2047. }
  2048. #if defined(CONFIG_MTK_AEE_FEATURE)
  2049. aed_md_exception_api(ex_log_addr, ex_log_len, md_img_addr, md_img_len, buff, db_opt);
  2050. #endif
  2051. kfree(buff);
  2052. }
  2053. #ifdef MD_UMOLY_EE_SUPPORT
  2054. static void ccci_md_ee_info_dump(struct ccci_modem *md)
  2055. {
  2056. char *ex_info; /*[EE_BUF_LEN] = ""; */
  2057. char *i_bit_ex_info = NULL;/*[EE_BUF_LEN] = "\n[Others] May I-Bit dis too long\n";*/
  2058. char buf_fail[] = "Fail alloc mem for exception\n";
  2059. int db_opt = (DB_OPT_DEFAULT | DB_OPT_FTRACE);
  2060. int dump_flag = 0;
  2061. int core_id;
  2062. char *ex_info_temp = NULL;/*[EE_BUF_LEN] = "";*/
  2063. DEBUG_INFO_T *debug_info = &md->debug_info;
  2064. unsigned char c;
  2065. EX_PL_LOG_T *ex_pl_info = (EX_PL_LOG_T *)md->ex_pl_info;
  2066. struct rtc_time tm;
  2067. struct timeval tv = { 0 };
  2068. struct timeval tv_android = { 0 };
  2069. struct rtc_time tm_android;
  2070. ex_info = kmalloc(EE_BUF_LEN_UMOLY, GFP_ATOMIC);
  2071. if (ex_info == NULL) {
  2072. CCCI_EXP_MSG(md->index, KERN, "Fail alloc Mem for ex_info!\n");
  2073. goto err_exit;
  2074. }
  2075. ex_info_temp = kmalloc(EE_BUF_LEN_UMOLY, GFP_ATOMIC);
  2076. if (ex_info_temp == NULL) {
  2077. CCCI_EXP_MSG(md->index, KERN, "Fail alloc Mem for ex_info_temp!\n");
  2078. goto err_exit;
  2079. }
  2080. do_gettimeofday(&tv);
  2081. tv_android = tv;
  2082. rtc_time_to_tm(tv.tv_sec, &tm);
  2083. tv_android.tv_sec -= sys_tz.tz_minuteswest * 60;
  2084. rtc_time_to_tm(tv_android.tv_sec, &tm_android);
  2085. CCCI_EXP_INF_MSG(md->index, KERN, "Sync:%d%02d%02d %02d:%02d:%02d.%u(%02d:%02d:%02d.%03d(TZone))\n",
  2086. tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
  2087. tm.tm_hour, tm.tm_min, tm.tm_sec,
  2088. (unsigned int)tv.tv_usec,
  2089. tm_android.tm_hour, tm_android.tm_min, tm_android.tm_sec, (unsigned int)tv_android.tv_usec);
  2090. for (core_id = 0; core_id < md->ex_core_num; core_id++) {
  2091. if (core_id == 1) {
  2092. snprintf(ex_info_temp, EE_BUF_LEN_UMOLY, "%s", ex_info);
  2093. debug_info = &md->debug_info1[core_id - 1];
  2094. } else if (core_id > 1) {
  2095. snprintf(ex_info_temp, EE_BUF_LEN_UMOLY, "%smd%d:%s", ex_info_temp, md->index + 1, ex_info);
  2096. debug_info = &md->debug_info1[core_id - 1];
  2097. }
  2098. CCCI_ERR_MSG(md->index, KERN, "exception type(%d):%s\n", debug_info->type,
  2099. debug_info->name ? : "Unknown");
  2100. switch (debug_info->type) {
  2101. case MD_EX_DUMP_ASSERT:
  2102. CCCI_EXP_MSG(md->index, KERN, "filename = %s\n", debug_info->assert.file_name);
  2103. CCCI_EXP_MSG(md->index, KERN, "line = %d\n", debug_info->assert.line_num);
  2104. CCCI_EXP_MSG(md->index, KERN, "para0 = %d, para1 = %d, para2 = %d\n",
  2105. debug_info->assert.parameters[0],
  2106. debug_info->assert.parameters[1], debug_info->assert.parameters[2]);
  2107. snprintf(ex_info, EE_BUF_LEN_UMOLY,
  2108. "%s\n[%s] file:%s line:%d\np1:0x%08x\np2:0x%08x\np3:0x%08x\n\n",
  2109. debug_info->core_name,
  2110. debug_info->name,
  2111. debug_info->assert.file_name,
  2112. debug_info->assert.line_num,
  2113. debug_info->assert.parameters[0],
  2114. debug_info->assert.parameters[1], debug_info->assert.parameters[2]);
  2115. break;
  2116. case MD_EX_DUMP_3P_EX:
  2117. case MD_EX_CC_C2K_EXCEPTION:
  2118. CCCI_EXP_MSG(md->index, KERN, "fatal error code 1 = 0x%08X\n",
  2119. debug_info->fatal_error.err_code1);
  2120. CCCI_EXP_MSG(md->index, KERN, "fatal error code 2 = 0x%08X\n",
  2121. debug_info->fatal_error.err_code2);
  2122. CCCI_EXP_MSG(md->index, KERN, "fatal error code 3 = 0x%08X\n",
  2123. debug_info->fatal_error.err_code3);
  2124. CCCI_EXP_MSG(md->index, KERN, "fatal error offender %s\n", debug_info->fatal_error.offender);
  2125. if (debug_info->fatal_error.offender[0] != '\0') {
  2126. snprintf(ex_info, EE_BUF_LEN_UMOLY,
  2127. "%s\n[%s] err_code1:0x%08X err_code2:0x%08X erro_code3:0x%08X\nMD Offender:%s\n%s\n",
  2128. debug_info->core_name, debug_info->name, debug_info->fatal_error.err_code1,
  2129. debug_info->fatal_error.err_code2, debug_info->fatal_error.err_code3,
  2130. debug_info->fatal_error.offender, debug_info->fatal_error.ExStr);
  2131. } else {
  2132. snprintf(ex_info, EE_BUF_LEN_UMOLY,
  2133. "%s\n[%s] err_code1:0x%08X err_code2:0x%08X err_code3:0x%08X\n%s\n",
  2134. debug_info->core_name, debug_info->name, debug_info->fatal_error.err_code1,
  2135. debug_info->fatal_error.err_code2, debug_info->fatal_error.err_code3,
  2136. debug_info->fatal_error.ExStr);
  2137. }
  2138. break;
  2139. case MD_EX_DUMP_2P_EX:
  2140. CCCI_EXP_MSG(md->index, KERN, "fatal error code 1 = 0x%08X\n\n",
  2141. debug_info->fatal_error.err_code1);
  2142. CCCI_EXP_MSG(md->index, KERN, "fatal error code 2 = 0x%08X\n\n",
  2143. debug_info->fatal_error.err_code2);
  2144. snprintf(ex_info, EE_BUF_LEN_UMOLY, "%s\n[%s] err_code1:0x%08X err_code2:0x%08X\n\n",
  2145. debug_info->core_name, debug_info->name, debug_info->fatal_error.err_code1,
  2146. debug_info->fatal_error.err_code2);
  2147. break;
  2148. case MD_EX_DUMP_EMI_CHECK:
  2149. CCCI_EXP_MSG(md->index, KERN, "md_emi_check: 0x%08X, 0x%08X, %02d, 0x%08X\n\n",
  2150. debug_info->data.data0, debug_info->data.data1,
  2151. debug_info->data.channel, debug_info->data.reserved);
  2152. snprintf(ex_info, EE_BUF_LEN_UMOLY, "%s\n[emi_chk] 0x%08X, 0x%08X, %02d, 0x%08X\n\n",
  2153. debug_info->core_name, debug_info->data.data0, debug_info->data.data1,
  2154. debug_info->data.channel, debug_info->data.reserved);
  2155. break;
  2156. case MD_EX_DUMP_UNKNOWN:
  2157. default: /* Only display exception name */
  2158. snprintf(ex_info, EE_BUF_LEN_UMOLY, "%s\n[%s]\n", debug_info->core_name, debug_info->name);
  2159. break;
  2160. }
  2161. }
  2162. if (md->ex_core_num > 1) {
  2163. CCCI_EXP_INF_MSG(md->index, KERN, "%s+++++++%s", ex_info_temp, ex_info);
  2164. snprintf(ex_info_temp, EE_BUF_LEN_UMOLY, "%smd%d:%s", ex_info_temp, md->index + 1, ex_info);
  2165. snprintf(ex_info, EE_BUF_LEN_UMOLY, "%s", ex_info_temp);
  2166. debug_info = &md->debug_info;
  2167. /*CCCI_INF_MSG(md->index, KERN, "=======***==================\n");
  2168. CCCI_INF_MSG(md->index, KERN, "Core Id(%d/%lu):%s", core_id, sizeof(ex_info_temp), ex_info);
  2169. CCCI_INF_MSG(md->index, KERN, "===========================\n"); */
  2170. } else if (md->ex_core_num == 0)
  2171. snprintf(ex_info, EE_BUF_LEN_UMOLY, "\n");
  2172. /* Add additional info */
  2173. switch (debug_info->more_info) {
  2174. case MD_EE_CASE_ONLY_SWINT:
  2175. strcat(ex_info, "\nOnly SWINT case\n");
  2176. break;
  2177. case MD_EE_CASE_SWINT_MISSING:
  2178. strcat(ex_info, "\nSWINT missing case\n");
  2179. break;
  2180. case MD_EE_CASE_ONLY_EX:
  2181. strcat(ex_info, "\nOnly EX case\n");
  2182. break;
  2183. case MD_EE_CASE_ONLY_EX_OK:
  2184. strcat(ex_info, "\nOnly EX_OK case\n");
  2185. break;
  2186. case MD_EE_CASE_AP_MASK_I_BIT_TOO_LONG:
  2187. i_bit_ex_info = kmalloc(EE_BUF_LEN_UMOLY, GFP_ATOMIC);
  2188. if (i_bit_ex_info == NULL) {
  2189. CCCI_EXP_MSG(md->index, KERN, "Fail alloc Mem for i_bit_ex_info!\n");
  2190. break;
  2191. }
  2192. snprintf(i_bit_ex_info, EE_BUF_LEN_UMOLY, "\n[Others] May I-Bit dis too long\n");
  2193. strcat(i_bit_ex_info, ex_info);
  2194. strcpy(ex_info, i_bit_ex_info);
  2195. break;
  2196. case MD_EE_CASE_TX_TRG:
  2197. case MD_EE_CASE_ISR_TRG:
  2198. strcat(ex_info, "\n[Others] May I-Bit dis too long\n");
  2199. break;
  2200. case MD_EE_CASE_NO_RESPONSE:
  2201. /* use strcpy, otherwise if this happens after a MD EE, the former EE info will be printed out */
  2202. strcpy(ex_info, "\n[Others] MD long time no response\n");
  2203. db_opt |= DB_OPT_FTRACE;
  2204. break;
  2205. case MD_EE_CASE_WDT:
  2206. strcpy(ex_info, "\n[Others] MD watchdog timeout interrupt\n");
  2207. break;
  2208. default:
  2209. break;
  2210. }
  2211. /* get ELM_status field from MD side */
  2212. c = ex_pl_info->envinfo.ELM_status;
  2213. CCCI_EXP_INF_MSG(md->index, KERN, "ELM_status: %x\n", c);
  2214. switch (c) {
  2215. case 0xFF:
  2216. strcat(ex_info, "\nno ELM info\n");
  2217. break;
  2218. case 0xAE:
  2219. strcat(ex_info, "\nELM rlat:FAIL\n");
  2220. break;
  2221. case 0xBE:
  2222. strcat(ex_info, "\nELM wlat:FAIL\n");
  2223. break;
  2224. case 0xDE:
  2225. strcat(ex_info, "\nELM r/wlat:PASS\n");
  2226. break;
  2227. default:
  2228. break;
  2229. }
  2230. /* Dump MD EE info */
  2231. CCCI_EXP_INF_MSG(md->index, KERN, "Dump MD EX log, 0x%x, 0x%x\n", debug_info->more_info,
  2232. (unsigned int)md->boot_stage);
  2233. if (debug_info->more_info == MD_EE_CASE_NORMAL && md->boot_stage == MD_BOOT_STAGE_0 &&
  2234. md->flight_mode == MD_FIGHT_MODE_NONE) {
  2235. ccci_mem_dump(md->index, md->ex_pl_info, MD_HS1_FAIL_DUMP_SIZE/*sizeof(EX_PL_LOG_T)*/);
  2236. /* MD will not fill in share memory before we send runtime data */
  2237. dump_flag = CCCI_AED_DUMP_EX_PKT;
  2238. } else {
  2239. #if 1
  2240. ccci_mem_dump(md->index, md->smem_layout.ccci_exp_smem_base_vir, (2048 + 512));
  2241. ccci_mem_dump(md->index, (md->smem_layout.ccci_exp_smem_mdss_debug_vir + 6 * 1024), 2048);
  2242. #else
  2243. ccci_mem_dump(md->index, md->smem_layout.ccci_exp_smem_base_vir, md->smem_layout.ccci_exp_dump_size);
  2244. #endif
  2245. /* otherwise always dump whole share memory,
  2246. as MD will fill debug log into its 2nd 1K region after bootup */
  2247. dump_flag = CCCI_AED_DUMP_EX_MEM;
  2248. if (debug_info->more_info == MD_EE_CASE_NO_RESPONSE)
  2249. dump_flag |= CCCI_AED_DUMP_CCIF_REG;
  2250. }
  2251. /* Dump MD image memory */
  2252. CCCI_EXP_INF_MSG(md->index, KERN, "Dump MD image memory\n");
  2253. ccci_mem_dump(md->index, (void *)md->mem_layout.md_region_vir, MD_IMG_DUMP_SIZE);
  2254. /* Dump MD memory layout */
  2255. CCCI_EXP_INF_MSG(md->index, KERN, "Dump MD layout struct\n");
  2256. ccci_mem_dump(md->index, &md->mem_layout, sizeof(struct ccci_mem_layout));
  2257. /* Dump MD register */
  2258. md->ops->dump_info(md, DUMP_FLAG_REG, NULL, 0);
  2259. err_exit:
  2260. md->boot_stage = MD_BOOT_STAGE_EXCEPTION;
  2261. /* update here to maintain handshake stage info during exception handling */
  2262. if (debug_info->type == MD_EX_TYPE_C2K_ERROR)
  2263. CCCI_EXP_INF_MSG(md->index, KERN, "C2K EE, No need trigger DB\n");
  2264. else if ((debug_info->type == MD_EX_DUMP_EMI_CHECK) && (Is_MD_EMI_voilation() == 0))
  2265. CCCI_EXP_INF_MSG(md->index, KERN, "Not MD EMI violation, No need trigger DB\n");
  2266. else if (ex_info == NULL)
  2267. ccci_aed(md, dump_flag, buf_fail, db_opt);
  2268. else
  2269. ccci_aed(md, dump_flag, ex_info, db_opt);
  2270. if (debug_info->more_info == MD_EE_CASE_ONLY_SWINT)
  2271. md->ops->dump_info(md, DUMP_FLAG_QUEUE_0 | DUMP_FLAG_CCIF | DUMP_FLAG_CCIF_REG, NULL, 0);
  2272. kfree(ex_info);
  2273. kfree(ex_info_temp);
  2274. kfree(i_bit_ex_info);
  2275. }
  2276. static char md_ee_plstr[MD_EX_PL_FATALE_TOTAL + MD_EX_OTHER_CORE_EXCEPTIN - MD_EX_CC_INVALID_EXCEPTION][32] = {
  2277. "INVALID",
  2278. "Fatal error (undefine)",
  2279. "Fatal error (swi)",
  2280. "Fatal error (prefetch abort)",
  2281. "Fatal error (data abort)",
  2282. "Fatal error (stack)",
  2283. "Fatal error (task)",
  2284. "Fatal error (buff)",
  2285. "Fatal error (CC invalid)",
  2286. "Fatal error (CC PCore)",
  2287. "Fatal error (CC L1Core)",
  2288. "Fatal error (CC CS)",
  2289. "Fatal error (CC MD32)",
  2290. "Fatal error (CC C2K)",
  2291. "Fatal error (CC spc)"
  2292. };
  2293. /*
  2294. static char md_ee_plInvalid[MD_EX_CC_MD32_EXCEPTION - MD_EX_CC_INVALID_EXCEPTION + 1][32] = {
  2295. "CC Invalid Exception",
  2296. "CC PCore Exception",
  2297. "CC L1Core Exception",
  2298. "CC CS Exception",
  2299. "CC MD32 Exception"
  2300. };
  2301. */
  2302. void strmncopy(char *src, char *dst, int src_len, int dst_len)
  2303. {
  2304. int temp_m, temp_n, temp_i;
  2305. temp_m = src_len - 1;
  2306. temp_n = dst_len - 1;
  2307. temp_n = (temp_m > temp_n) ? temp_n : temp_m;
  2308. for (temp_i = 0; temp_i < temp_n; temp_i++) {
  2309. dst[temp_i] = src[temp_i];
  2310. if (dst[temp_i] == 0x00)
  2311. break;
  2312. }
  2313. CCCI_DBG_MSG(-1, KERN, "copy str(%d) %s\n", temp_i, dst);
  2314. }
  2315. /* todo: copy error code can convert a mini function */
  2316. static void ccci_md_exp_change(struct ccci_modem *md)
  2317. {
  2318. EX_OVERVIEW_T *ex_overview;
  2319. int ee_type, ee_case;
  2320. DEBUG_INFO_T *debug_info = &md->debug_info;
  2321. int core_id;
  2322. unsigned char off_core_num; /* number of offender core: need parse */
  2323. unsigned int temp_i;
  2324. EX_PL_LOG_T *ex_pl_info = (EX_PL_LOG_T *)md->ex_pl_info;
  2325. EX_PL_LOG_T *ex_PLloginfo;
  2326. EX_CS_LOG_T *ex_csLogInfo;
  2327. EX_MD32_LOG_T *ex_md32LogInfo;
  2328. if (debug_info == NULL)
  2329. return;
  2330. CCCI_EXP_INF_MSG(md->index, KERN, "ccci_md_exp_change, ee_case(0x%x)\n", debug_info->more_info);
  2331. ee_case = debug_info->more_info;
  2332. memset(debug_info, 0, sizeof(DEBUG_INFO_T));
  2333. debug_info->more_info = ee_case;
  2334. off_core_num = 0;
  2335. ex_overview = (EX_OVERVIEW_T *) md->smem_layout.ccci_exp_rec_base_vir;
  2336. if ((debug_info->more_info == MD_EE_CASE_NORMAL) && (md->boot_stage == MD_BOOT_STAGE_0) &&
  2337. (md->flight_mode != MD_FIGHT_MODE_ENTER)) {
  2338. ex_PLloginfo = ex_pl_info;
  2339. core_id = MD_CORE_NUM;
  2340. off_core_num++;
  2341. snprintf(debug_info->core_name, MD_CORE_NAME_DEBUG, "(MCU_PCORE)");
  2342. goto PL_CORE_PROC;
  2343. }
  2344. for (core_id = 0; core_id < MD_CORE_NUM; core_id++) {
  2345. CCCI_DBG_MSG(md->index, KERN, "core_id(%x/%x): offset=%x, if_offender=%d, %s\n", (core_id + 1),
  2346. ex_overview->core_num, ex_overview->main_reson[core_id].core_offset,
  2347. ex_overview->main_reson[core_id].is_offender, ex_overview->main_reson[core_id].core_name);
  2348. if (ex_overview->main_reson[core_id].is_offender) {
  2349. off_core_num++;
  2350. /* (core name): PCORE/L1CORE/CS_ICC/CS_IMC/CS_MPC/MD32_BRP/MD32_DFE/MD32_RAKE */
  2351. debug_info->core_name[0] = '(';
  2352. for (temp_i = 1; temp_i < MD_CORE_NAME_LEN; temp_i++) {
  2353. debug_info->core_name[temp_i] = ex_overview->main_reson[core_id].core_name[temp_i - 1];
  2354. if (debug_info->core_name[temp_i] == '\0')
  2355. break;
  2356. }
  2357. debug_info->core_name[temp_i++] = ')';
  2358. debug_info->core_name[temp_i] = '\0';
  2359. CCCI_EXP_INF_MSG(md->index, KERN, "core_id(0x%x/%d), %s\n", core_id, off_core_num,
  2360. debug_info->core_name);
  2361. ex_pl_info->envinfo.ELM_status = 0;
  2362. switch (core_id) {
  2363. case MD_PCORE:
  2364. case MD_L1CORE:
  2365. ex_PLloginfo =
  2366. (EX_PL_LOG_T *) ((char *)ex_overview +
  2367. ex_overview->main_reson[core_id].core_offset);
  2368. ex_pl_info->envinfo.ELM_status = ex_PLloginfo->envinfo.ELM_status;
  2369. PL_CORE_PROC:
  2370. ee_type = ex_PLloginfo->header.ex_type;
  2371. debug_info->type = ee_type;
  2372. ee_case = ee_type;
  2373. CCCI_EXP_INF_MSG(md->index, KERN, "PL ex type(0x%x)\n", ee_type);
  2374. switch (ee_type) {
  2375. case MD_EX_PL_INVALID:
  2376. debug_info->name = "INVALID";
  2377. break;
  2378. case MD_EX_CC_INVALID_EXCEPTION:
  2379. case MD_EX_CC_PCORE_EXCEPTION:
  2380. case MD_EX_CC_L1CORE_EXCEPTION:
  2381. case MD_EX_CC_CS_EXCEPTION:
  2382. case MD_EX_CC_MD32_EXCEPTION:
  2383. case MD_EX_CC_C2K_EXCEPTION:
  2384. /* Fall through */
  2385. case MD_EX_CC_ARM7_EXCEPTION:
  2386. /*
  2387. md1:(MCU_PCORE)
  2388. [Fatal error (CC xxx)] err_code1:0x00000xx err_code2:0x00xxx err_code3:0xxxx
  2389. Offender: */
  2390. ee_type = ee_type - MD_EX_CC_INVALID_EXCEPTION + MD_EX_PL_FATALE_TOTAL;
  2391. case MD_EX_PL_UNDEF:
  2392. case MD_EX_PL_SWI:
  2393. case MD_EX_PL_PREF_ABT:
  2394. case MD_EX_PL_DATA_ABT:
  2395. case MD_EX_PL_STACKACCESS:
  2396. case MD_EX_PL_FATALERR_TASK:
  2397. case MD_EX_PL_FATALERR_BUF:
  2398. /* all offender is zero, goto from tail of function, reparser. */
  2399. /* the only one case: none offender, c2k ee */
  2400. if ((core_id == MD_CORE_NUM) && (ee_type ==
  2401. (MD_EX_CC_C2K_EXCEPTION - MD_EX_CC_INVALID_EXCEPTION +
  2402. MD_EX_PL_FATALE_TOTAL)))
  2403. debug_info->type = MD_EX_CC_C2K_EXCEPTION;
  2404. else
  2405. debug_info->type = MD_EX_DUMP_3P_EX;
  2406. debug_info->name = md_ee_plstr[ee_type];
  2407. if (ex_PLloginfo->content.fatalerr.ex_analy.owner[0] != 0xCC) {
  2408. strmncopy(ex_PLloginfo->content.fatalerr.ex_analy.owner,
  2409. debug_info->fatal_error.offender,
  2410. sizeof(ex_PLloginfo->content.fatalerr.ex_analy.owner),
  2411. sizeof(debug_info->fatal_error.offender));
  2412. CCCI_INF_MSG(md->index, KERN, "offender: %s\n",
  2413. debug_info->fatal_error.offender);
  2414. }
  2415. debug_info->fatal_error.err_code1 =
  2416. ex_PLloginfo->content.fatalerr.error_code.code1;
  2417. debug_info->fatal_error.err_code2 =
  2418. ex_PLloginfo->content.fatalerr.error_code.code2;
  2419. debug_info->fatal_error.err_code3 =
  2420. ex_PLloginfo->content.fatalerr.error_code.code3;
  2421. if (ex_PLloginfo->content.fatalerr.ex_analy.is_cadefa_sup)
  2422. debug_info->fatal_error.ExStr = "CaDeFa Supported\n";
  2423. else
  2424. debug_info->fatal_error.ExStr = "";
  2425. break;
  2426. case MD_EX_PL_ASSERT_FAIL:
  2427. case MD_EX_PL_ASSERT_DUMP:
  2428. case MD_EX_PL_ASSERT_NATIVE:
  2429. debug_info->type = MD_EX_DUMP_ASSERT;/* = MD_EX_TYPE_ASSERT; */
  2430. debug_info->name = "ASSERT";
  2431. CCCI_DBG_MSG(md->index, KERN, "p filename1(%s)\n",
  2432. ex_PLloginfo->content.assert.filepath);
  2433. strmncopy(ex_PLloginfo->content.assert.filepath,
  2434. debug_info->assert.file_name,
  2435. sizeof(ex_PLloginfo->content.assert.filepath),
  2436. sizeof(debug_info->assert.file_name));
  2437. CCCI_DBG_MSG(md->index, KERN,
  2438. "p filename2:(%s)\n", debug_info->assert.file_name);
  2439. debug_info->assert.line_num = ex_PLloginfo->content.assert.linenumber;
  2440. debug_info->assert.parameters[0] = ex_PLloginfo->content.assert.para[0];
  2441. debug_info->assert.parameters[1] = ex_PLloginfo->content.assert.para[1];
  2442. debug_info->assert.parameters[2] = ex_PLloginfo->content.assert.para[2];
  2443. break;
  2444. case EMI_MPU_VIOLATION:
  2445. debug_info->type = MD_EX_DUMP_3P_EX;
  2446. ee_case = MD_EX_TYPE_FATALERR_BUF;
  2447. debug_info->name = "Fatal error (rmpu violation)";
  2448. debug_info->fatal_error.err_code1 =
  2449. ex_PLloginfo->content.fatalerr.error_code.code1;
  2450. debug_info->fatal_error.err_code2 =
  2451. ex_PLloginfo->content.fatalerr.error_code.code2;
  2452. debug_info->fatal_error.err_code3 =
  2453. ex_PLloginfo->content.fatalerr.error_code.code3;
  2454. debug_info->fatal_error.ExStr = "EMI MPU VIOLATION\n";
  2455. break;
  2456. default:
  2457. debug_info->name = "UNKNOWN Exception";
  2458. break;
  2459. }
  2460. debug_info->ext_mem = ex_PLloginfo;
  2461. debug_info->ext_size = sizeof(EX_PL_LOG_T);
  2462. break;
  2463. case MD_CS_ICC:
  2464. case MD_CS_IMC:
  2465. case MD_CS_MPC:
  2466. ex_csLogInfo =
  2467. (EX_CS_LOG_T *) ((char *)ex_overview +
  2468. ex_overview->main_reson[core_id].core_offset);
  2469. ee_type = ex_csLogInfo->except_type;
  2470. CCCI_EXP_INF_MSG(md->index, KERN, "cs ex type(0x%x)\n", ee_type);
  2471. switch (ee_type) {
  2472. case CS_EXCEPTION_ASSERTION:
  2473. debug_info->type = MD_EX_DUMP_ASSERT;
  2474. ee_case = MD_EX_TYPE_ASSERT;
  2475. debug_info->name = "ASSERT";
  2476. strmncopy(ex_csLogInfo->except_content.assert.file_name,
  2477. debug_info->assert.file_name,
  2478. sizeof(ex_csLogInfo->except_content.assert.file_name),
  2479. sizeof(debug_info->assert.file_name));
  2480. debug_info->assert.line_num = ex_csLogInfo->except_content.assert.line_num;
  2481. debug_info->assert.parameters[0] = ex_csLogInfo->except_content.assert.para1;
  2482. debug_info->assert.parameters[1] = ex_csLogInfo->except_content.assert.para2;
  2483. debug_info->assert.parameters[2] = ex_csLogInfo->except_content.assert.para3;
  2484. break;
  2485. case CS_EXCEPTION_FATAL_ERROR:
  2486. debug_info->type = MD_EX_DUMP_2P_EX;
  2487. ee_case = MD_EX_TYPE_FATALERR_TASK;
  2488. debug_info->name = "Fatal error";
  2489. debug_info->fatal_error.err_code1 =
  2490. ex_csLogInfo->except_content.fatalerr.error_code1;
  2491. debug_info->fatal_error.err_code2 =
  2492. ex_csLogInfo->except_content.fatalerr.error_code2;
  2493. break;
  2494. case CS_EXCEPTION_CTI_EVENT:
  2495. debug_info->name = "CC CTI Exception";
  2496. break;
  2497. case CS_EXCEPTION_UNKNOWN:
  2498. default:
  2499. debug_info->name = "UNKNOWN Exception";
  2500. break;
  2501. }
  2502. debug_info->ext_mem = ex_csLogInfo;
  2503. debug_info->ext_size = sizeof(EX_CS_LOG_T);
  2504. break;
  2505. case MD_MD32_DFE:
  2506. case MD_MD32_BRP:
  2507. case MD_MD32_RAKE:
  2508. ex_md32LogInfo = (EX_MD32_LOG_T *) ((char *)ex_overview +
  2509. ex_overview->main_reson[core_id].core_offset);
  2510. ee_type = ex_md32LogInfo->except_type;
  2511. CCCI_EXP_INF_MSG(md->index, KERN, "md32 ex type(0x%x), name: %s\n", ee_type,
  2512. ex_md32LogInfo->except_content.assert.file_name);
  2513. switch (ex_md32LogInfo->md32_active_mode) {
  2514. case 1:
  2515. strcat(debug_info->core_name, MD32_FDD_ROCODE);
  2516. break;
  2517. case 2:
  2518. strcat(debug_info->core_name, MD32_TDD_ROCODE);
  2519. break;
  2520. default:
  2521. break;
  2522. }
  2523. switch (ee_type) {
  2524. case CMIF_MD32_EX_ASSERT_LINE:
  2525. case CMIF_MD32_EX_ASSERT_EXT:
  2526. debug_info->type = MD_EX_DUMP_ASSERT;
  2527. ee_case = MD_EX_TYPE_ASSERT;
  2528. debug_info->name = "ASSERT";
  2529. strmncopy(ex_md32LogInfo->except_content.assert.file_name,
  2530. debug_info->assert.file_name,
  2531. sizeof(ex_md32LogInfo->except_content.assert.file_name),
  2532. sizeof(debug_info->assert.file_name));
  2533. debug_info->assert.line_num = ex_md32LogInfo->except_content.assert.line_num;
  2534. debug_info->assert.parameters[0] =
  2535. ex_md32LogInfo->except_content.assert.ex_code[0];
  2536. debug_info->assert.parameters[1] =
  2537. ex_md32LogInfo->except_content.assert.ex_code[1];
  2538. debug_info->assert.parameters[2] =
  2539. ex_md32LogInfo->except_content.assert.ex_code[2];
  2540. break;
  2541. case CMIF_MD32_EX_FATAL_ERROR:
  2542. case CMIF_MD32_EX_FATAL_ERROR_EXT:
  2543. debug_info->type = MD_EX_DUMP_2P_EX;
  2544. ee_case = MD_EX_TYPE_FATALERR_TASK;
  2545. debug_info->name = "Fatal error";
  2546. debug_info->fatal_error.err_code1 =
  2547. ex_md32LogInfo->except_content.fatalerr.ex_code[0];
  2548. debug_info->fatal_error.err_code2 =
  2549. ex_md32LogInfo->except_content.fatalerr.ex_code[1];
  2550. break;
  2551. case CS_EXCEPTION_CTI_EVENT:
  2552. case CS_EXCEPTION_UNKNOWN:
  2553. default:
  2554. debug_info->name = "UNKNOWN Exception";
  2555. break;
  2556. }
  2557. debug_info->ext_mem = ex_md32LogInfo;
  2558. debug_info->ext_size = sizeof(EX_MD32_LOG_T);
  2559. break;
  2560. }
  2561. if (off_core_num < MD_CORE_NUM) {
  2562. debug_info->md_image = (void *)md->mem_layout.md_region_vir;
  2563. debug_info->md_size = MD_IMG_DUMP_SIZE;
  2564. debug_info = &md->debug_info1[off_core_num - 1];
  2565. memset(debug_info, 0, sizeof(DEBUG_INFO_T));
  2566. if (off_core_num == 1)
  2567. md->ex_type = ee_case;
  2568. }
  2569. }
  2570. }
  2571. if (off_core_num == 0) {
  2572. ex_PLloginfo = (EX_PL_LOG_T *) ((char *)ex_overview +
  2573. ex_overview->main_reson[MD_PCORE].core_offset);
  2574. ex_pl_info->envinfo.ELM_status = ex_PLloginfo->envinfo.ELM_status;
  2575. off_core_num++;
  2576. core_id = MD_CORE_NUM;
  2577. snprintf(debug_info->core_name, MD_CORE_NAME_DEBUG, "(MCU_PCORE)");
  2578. goto PL_CORE_PROC;
  2579. }
  2580. md->ex_core_num = off_core_num;
  2581. CCCI_EXP_INF_MSG(md->index, KERN, "core_ex_num(%d/%d)\n", off_core_num, md->ex_core_num);
  2582. }
  2583. #endif
  2584. static void ccci_ee_info_dump(struct ccci_modem *md)
  2585. {
  2586. char *ex_info;/* [EE_BUF_LEN] = ""; */
  2587. char *i_bit_ex_info = NULL;/* [EE_BUF_LEN] = "\n[Others] May I-Bit dis too long\n"; */
  2588. char buf_fail[] = "Fail alloc mem for exception\n";
  2589. int db_opt = (DB_OPT_DEFAULT | DB_OPT_FTRACE);
  2590. int dump_flag = 0;
  2591. DEBUG_INFO_T *debug_info = &md->debug_info;
  2592. unsigned char c;
  2593. struct rtc_time tm;
  2594. struct timeval tv = { 0 };
  2595. struct timeval tv_android = { 0 };
  2596. struct rtc_time tm_android;
  2597. do_gettimeofday(&tv);
  2598. tv_android = tv;
  2599. rtc_time_to_tm(tv.tv_sec, &tm);
  2600. tv_android.tv_sec -= sys_tz.tz_minuteswest * 60;
  2601. rtc_time_to_tm(tv_android.tv_sec, &tm_android);
  2602. CCCI_INF_MSG(md->index, KERN, "Sync:%d%02d%02d %02d:%02d:%02d.%u(%02d:%02d:%02d.%03d(TZone))\n",
  2603. tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
  2604. tm.tm_hour, tm.tm_min, tm.tm_sec,
  2605. (unsigned int)tv.tv_usec,
  2606. tm_android.tm_hour, tm_android.tm_min, tm_android.tm_sec, (unsigned int)tv_android.tv_usec);
  2607. ex_info = kmalloc(EE_BUF_LEN, GFP_ATOMIC);
  2608. if (ex_info == NULL) {
  2609. CCCI_ERR_MSG(md->index, KERN, "Fail alloc Mem for ex_info!\n");
  2610. goto err_exit;
  2611. }
  2612. CCCI_INF_MSG(md->index, KERN, "exception type(%d):%s\n", debug_info->type, debug_info->name ? : "Unknown");
  2613. switch (debug_info->type) {
  2614. case MD_EX_TYPE_ASSERT_DUMP:
  2615. case MD_EX_TYPE_ASSERT:
  2616. CCCI_INF_MSG(md->index, KERN, "filename = %s\n", debug_info->assert.file_name);
  2617. CCCI_INF_MSG(md->index, KERN, "line = %d\n", debug_info->assert.line_num);
  2618. CCCI_INF_MSG(md->index, KERN, "para0 = %d, para1 = %d, para2 = %d\n",
  2619. debug_info->assert.parameters[0],
  2620. debug_info->assert.parameters[1], debug_info->assert.parameters[2]);
  2621. snprintf(ex_info, EE_BUF_LEN, "\n[%s] file:%s line:%d\np1:0x%08x\np2:0x%08x\np3:0x%08x\n",
  2622. debug_info->name,
  2623. debug_info->assert.file_name,
  2624. debug_info->assert.line_num,
  2625. debug_info->assert.parameters[0],
  2626. debug_info->assert.parameters[1], debug_info->assert.parameters[2]);
  2627. break;
  2628. case MD_EX_TYPE_UNDEF:
  2629. case MD_EX_TYPE_SWI:
  2630. case MD_EX_TYPE_PREF_ABT:
  2631. case MD_EX_TYPE_DATA_ABT:
  2632. case MD_EX_TYPE_FATALERR_BUF:
  2633. case MD_EX_TYPE_FATALERR_TASK:
  2634. case MD_EX_TYPE_C2K_ERROR:
  2635. CCCI_INF_MSG(md->index, KERN, "fatal error code 1 = %d\n", debug_info->fatal_error.err_code1);
  2636. CCCI_INF_MSG(md->index, KERN, "fatal error code 2 = %d\n", debug_info->fatal_error.err_code2);
  2637. CCCI_INF_MSG(md->index, KERN, "fatal error offender %s\n", debug_info->fatal_error.offender);
  2638. if (debug_info->fatal_error.offender[0] != '\0') {
  2639. snprintf(ex_info, EE_BUF_LEN, "\n[%s] err_code1:%d err_code2:%d\nMD Offender:%s\n",
  2640. debug_info->name, debug_info->fatal_error.err_code1, debug_info->fatal_error.err_code2,
  2641. debug_info->fatal_error.offender);
  2642. } else {
  2643. snprintf(ex_info, EE_BUF_LEN, "\n[%s] err_code1:%d err_code2:%d\n", debug_info->name,
  2644. debug_info->fatal_error.err_code1, debug_info->fatal_error.err_code2);
  2645. }
  2646. break;
  2647. case CC_MD1_EXCEPTION:
  2648. CCCI_INF_MSG(md->index, KERN, "fatal error code 1 = %d\n", debug_info->fatal_error.err_code1);
  2649. CCCI_INF_MSG(md->index, KERN, "fatal error code 2 = %d\n", debug_info->fatal_error.err_code2);
  2650. snprintf(ex_info, EE_BUF_LEN, "\n[%s] err_code1:%d err_code2:%d\n", debug_info->name,
  2651. debug_info->fatal_error.err_code1, debug_info->fatal_error.err_code2);
  2652. break;
  2653. case MD_EX_TYPE_EMI_CHECK:
  2654. CCCI_INF_MSG(md->index, KERN, "md_emi_check: %08X, %08X, %02d, %08X\n",
  2655. debug_info->data.data0, debug_info->data.data1,
  2656. debug_info->data.channel, debug_info->data.reserved);
  2657. snprintf(ex_info, EE_BUF_LEN, "\n[emi_chk] %08X, %08X, %02d, %08X\n",
  2658. debug_info->data.data0, debug_info->data.data1,
  2659. debug_info->data.channel, debug_info->data.reserved);
  2660. break;
  2661. case DSP_EX_TYPE_ASSERT:
  2662. CCCI_INF_MSG(md->index, KERN, "filename = %s\n", debug_info->dsp_assert.file_name);
  2663. CCCI_INF_MSG(md->index, KERN, "line = %d\n", debug_info->dsp_assert.line_num);
  2664. CCCI_INF_MSG(md->index, KERN, "exec unit = %s\n", debug_info->dsp_assert.execution_unit);
  2665. CCCI_INF_MSG(md->index, KERN, "para0 = %d, para1 = %d, para2 = %d\n",
  2666. debug_info->dsp_assert.parameters[0],
  2667. debug_info->dsp_assert.parameters[1], debug_info->dsp_assert.parameters[2]);
  2668. snprintf(ex_info, EE_BUF_LEN, "\n[%s] file:%s line:%d\nexec:%s\np1:%d\np2:%d\np3:%d\n",
  2669. debug_info->name, debug_info->assert.file_name, debug_info->assert.line_num,
  2670. debug_info->dsp_assert.execution_unit,
  2671. debug_info->dsp_assert.parameters[0],
  2672. debug_info->dsp_assert.parameters[1], debug_info->dsp_assert.parameters[2]);
  2673. break;
  2674. case DSP_EX_TYPE_EXCEPTION:
  2675. CCCI_INF_MSG(md->index, KERN, "exec unit = %s, code1:0x%08x\n",
  2676. debug_info->dsp_exception.execution_unit, debug_info->dsp_exception.code1);
  2677. snprintf(ex_info, EE_BUF_LEN, "\n[%s] exec:%s code1:0x%08x\n", debug_info->name,
  2678. debug_info->dsp_exception.execution_unit, debug_info->dsp_exception.code1);
  2679. break;
  2680. case DSP_EX_FATAL_ERROR:
  2681. CCCI_INF_MSG(md->index, KERN, "exec unit = %s\n", debug_info->dsp_fatal_err.execution_unit);
  2682. CCCI_INF_MSG(md->index, KERN, "err_code0 = 0x%08x, err_code1 = 0x%08x\n",
  2683. debug_info->dsp_fatal_err.err_code[0], debug_info->dsp_fatal_err.err_code[1]);
  2684. snprintf(ex_info, EE_BUF_LEN, "\n[%s] exec:%s err_code1:0x%08x err_code2:0x%08x\n",
  2685. debug_info->name, debug_info->dsp_fatal_err.execution_unit,
  2686. debug_info->dsp_fatal_err.err_code[0], debug_info->dsp_fatal_err.err_code[1]);
  2687. break;
  2688. default: /* Only display exception name */
  2689. snprintf(ex_info, EE_BUF_LEN, "\n[%s]\n", debug_info->name);
  2690. break;
  2691. }
  2692. /* Add additional info */
  2693. switch (debug_info->more_info) {
  2694. case MD_EE_CASE_ONLY_SWINT:
  2695. strcat(ex_info, "\nOnly SWINT case\n");
  2696. break;
  2697. case MD_EE_CASE_SWINT_MISSING:
  2698. strcat(ex_info, "\nSWINT missing case\n");
  2699. break;
  2700. case MD_EE_CASE_ONLY_EX:
  2701. strcat(ex_info, "\nOnly EX case\n");
  2702. break;
  2703. case MD_EE_CASE_ONLY_EX_OK:
  2704. strcat(ex_info, "\nOnly EX_OK case\n");
  2705. break;
  2706. case MD_EE_CASE_AP_MASK_I_BIT_TOO_LONG:
  2707. i_bit_ex_info = kmalloc(EE_BUF_LEN, GFP_ATOMIC);
  2708. if (i_bit_ex_info == NULL) {
  2709. CCCI_ERR_MSG(md->index, KERN, "Fail alloc Mem for i_bit_ex_info!\n");
  2710. break;
  2711. }
  2712. snprintf(i_bit_ex_info, EE_BUF_LEN, "\n[Others] May I-Bit dis too long\n");
  2713. strcat(i_bit_ex_info, ex_info);
  2714. strcpy(ex_info, i_bit_ex_info);
  2715. break;
  2716. case MD_EE_CASE_TX_TRG:
  2717. case MD_EE_CASE_ISR_TRG:
  2718. strcat(ex_info, "\n[Others] May I-Bit dis too long\n");
  2719. break;
  2720. case MD_EE_CASE_NO_RESPONSE:
  2721. /* use strcpy, otherwise if this happens after a MD EE, the former EE info will be printed out */
  2722. strcpy(ex_info, "\n[Others] MD long time no response\n");
  2723. db_opt |= DB_OPT_FTRACE;
  2724. break;
  2725. case MD_EE_CASE_WDT:
  2726. strcpy(ex_info, "\n[Others] MD watchdog timeout interrupt\n");
  2727. break;
  2728. default:
  2729. break;
  2730. }
  2731. /* get ELM_status field from MD side */
  2732. c = md->ex_info.envinfo.ELM_status;
  2733. CCCI_INF_MSG(md->index, KERN, "ELM_status: %x\n", c);
  2734. switch (c) {
  2735. case 0xFF:
  2736. strcat(ex_info, "\nno ELM info\n");
  2737. break;
  2738. case 0xAE:
  2739. strcat(ex_info, "\nELM rlat:FAIL\n");
  2740. break;
  2741. case 0xBE:
  2742. strcat(ex_info, "\nELM wlat:FAIL\n");
  2743. break;
  2744. case 0xDE:
  2745. strcat(ex_info, "\nELM r/wlat:PASS\n");
  2746. break;
  2747. default:
  2748. break;
  2749. }
  2750. err_exit:
  2751. /* Dump MD EE info */
  2752. CCCI_INF_MSG(md->index, KERN, "Dump MD EX log\n");
  2753. if ((md->index == MD_SYS3) || (debug_info->more_info == MD_EE_CASE_NORMAL && md->boot_stage == MD_BOOT_STAGE_0))
  2754. ccci_mem_dump(md->index, &md->ex_info, sizeof(EX_LOG_T));
  2755. else
  2756. ccci_mem_dump(md->index, md->smem_layout.ccci_exp_smem_base_vir, md->smem_layout.ccci_exp_dump_size);
  2757. /* Dump MD image memory */
  2758. CCCI_INF_MSG(md->index, KERN, "Dump MD image memory\n");
  2759. ccci_mem_dump(md->index, (void *)md->mem_layout.md_region_vir, MD_IMG_DUMP_SIZE);
  2760. /* Dump MD memory layout */
  2761. CCCI_INF_MSG(md->index, KERN, "Dump MD layout struct\n");
  2762. ccci_mem_dump(md->index, &md->mem_layout, sizeof(struct ccci_mem_layout));
  2763. /* Dump MD register */
  2764. md->ops->dump_info(md, DUMP_FLAG_REG, NULL, 0);
  2765. if (debug_info->more_info == MD_EE_CASE_NORMAL && md->boot_stage == MD_BOOT_STAGE_0) {
  2766. /* MD will not fill in share memory before we send runtime data */
  2767. dump_flag = CCCI_AED_DUMP_EX_PKT;
  2768. } else {/* otherwise always dump whole share memory,
  2769. as MD will fill debug log into its 2nd 1K region after bootup */
  2770. dump_flag = CCCI_AED_DUMP_EX_MEM;
  2771. if (debug_info->more_info == MD_EE_CASE_NO_RESPONSE)
  2772. dump_flag |= CCCI_AED_DUMP_CCIF_REG;
  2773. }
  2774. md->boot_stage = MD_BOOT_STAGE_EXCEPTION;
  2775. /* update here to maintain handshake stage info during exception handling */
  2776. if (debug_info->type == MD_EX_TYPE_C2K_ERROR && debug_info->fatal_error.err_code1 == MD_EX_C2K_FATAL_ERROR)
  2777. CCCI_INF_MSG(md->index, KERN, "C2K EE, No need trigger DB\n");
  2778. else if (debug_info->type == CC_MD1_EXCEPTION)
  2779. CCCI_INF_MSG(md->index, KERN, "MD1 EE, No need trigger DB\n");
  2780. else if (ex_info == NULL)
  2781. ccci_aed(md, dump_flag, buf_fail, db_opt);
  2782. else
  2783. ccci_aed(md, dump_flag, ex_info, db_opt);
  2784. if (debug_info->more_info == MD_EE_CASE_ONLY_SWINT)
  2785. md->ops->dump_info(md, DUMP_FLAG_QUEUE_0 | DUMP_FLAG_CCIF | DUMP_FLAG_CCIF_REG, NULL, 0);
  2786. kfree(ex_info);
  2787. kfree(i_bit_ex_info);
  2788. }
  2789. /*
  2790. * copy raw data (EX_LOG_T) received from modem into CCCI's DEBUG_INFO_T
  2791. */
  2792. static void ccci_md_exception(struct ccci_modem *md)
  2793. {
  2794. EX_LOG_T *ex_info;
  2795. int ee_type, ee_case;
  2796. DEBUG_INFO_T *debug_info = &md->debug_info;
  2797. if (debug_info == NULL)
  2798. return;
  2799. if ((md->index == MD_SYS3) ||
  2800. (debug_info->more_info == MD_EE_CASE_NORMAL && md->boot_stage == MD_BOOT_STAGE_0)) {
  2801. ex_info = &md->ex_info;
  2802. CCCI_DBG_MSG(md->index, KERN, "Parse ex info from ccci packages\n");
  2803. } else {
  2804. ex_info = (EX_LOG_T *) md->smem_layout.ccci_exp_rec_base_vir;
  2805. CCCI_DBG_MSG(md->index, KERN, "Parse ex info from shared memory\n");
  2806. }
  2807. ee_case = debug_info->more_info;
  2808. memset(debug_info, 0, sizeof(DEBUG_INFO_T));
  2809. ee_type = ex_info->header.ex_type;
  2810. debug_info->type = ee_type;
  2811. debug_info->more_info = ee_case;
  2812. md->ex_type = ee_type;
  2813. if (*((char *)ex_info + CCCI_EXREC_OFFSET_OFFENDER) != 0xCC) {
  2814. memcpy(debug_info->fatal_error.offender, (char *)ex_info + CCCI_EXREC_OFFSET_OFFENDER,
  2815. sizeof(debug_info->fatal_error.offender) - 1);
  2816. debug_info->fatal_error.offender[sizeof(debug_info->fatal_error.offender) - 1] = '\0';
  2817. } else {
  2818. debug_info->fatal_error.offender[0] = '\0';
  2819. }
  2820. switch (ee_type) {
  2821. case MD_EX_TYPE_INVALID:
  2822. debug_info->name = "INVALID";
  2823. break;
  2824. case MD_EX_TYPE_UNDEF:
  2825. debug_info->name = "Fatal error (undefine)";
  2826. debug_info->fatal_error.err_code1 = ex_info->content.fatalerr.error_code.code1;
  2827. debug_info->fatal_error.err_code2 = ex_info->content.fatalerr.error_code.code2;
  2828. break;
  2829. case MD_EX_TYPE_SWI:
  2830. debug_info->name = "Fatal error (swi)";
  2831. debug_info->fatal_error.err_code1 = ex_info->content.fatalerr.error_code.code1;
  2832. debug_info->fatal_error.err_code2 = ex_info->content.fatalerr.error_code.code2;
  2833. break;
  2834. case MD_EX_TYPE_PREF_ABT:
  2835. debug_info->name = "Fatal error (prefetch abort)";
  2836. debug_info->fatal_error.err_code1 = ex_info->content.fatalerr.error_code.code1;
  2837. debug_info->fatal_error.err_code2 = ex_info->content.fatalerr.error_code.code2;
  2838. break;
  2839. case MD_EX_TYPE_DATA_ABT:
  2840. debug_info->name = "Fatal error (data abort)";
  2841. debug_info->fatal_error.err_code1 = ex_info->content.fatalerr.error_code.code1;
  2842. debug_info->fatal_error.err_code2 = ex_info->content.fatalerr.error_code.code2;
  2843. break;
  2844. case MD_EX_TYPE_ASSERT:
  2845. debug_info->name = "ASSERT";
  2846. snprintf(debug_info->assert.file_name, sizeof(debug_info->assert.file_name),
  2847. ex_info->content.assert.filename);
  2848. debug_info->assert.line_num = ex_info->content.assert.linenumber;
  2849. debug_info->assert.parameters[0] = ex_info->content.assert.parameters[0];
  2850. debug_info->assert.parameters[1] = ex_info->content.assert.parameters[1];
  2851. debug_info->assert.parameters[2] = ex_info->content.assert.parameters[2];
  2852. break;
  2853. case MD_EX_TYPE_FATALERR_TASK:
  2854. debug_info->name = "Fatal error (task)";
  2855. debug_info->fatal_error.err_code1 = ex_info->content.fatalerr.error_code.code1;
  2856. debug_info->fatal_error.err_code2 = ex_info->content.fatalerr.error_code.code2;
  2857. break;
  2858. case MD_EX_TYPE_C2K_ERROR:
  2859. debug_info->name = "Fatal error (C2K_EXP)";
  2860. debug_info->fatal_error.err_code1 = ex_info->content.fatalerr.error_code.code1;
  2861. debug_info->fatal_error.err_code2 = ex_info->content.fatalerr.error_code.code2;
  2862. break;
  2863. case CC_MD1_EXCEPTION:
  2864. debug_info->name = "Fatal error (LTE_EXP)";
  2865. debug_info->fatal_error.err_code1 = ex_info->content.fatalerr.error_code.code1;
  2866. debug_info->fatal_error.err_code2 = ex_info->content.fatalerr.error_code.code2;
  2867. break;
  2868. case MD_EX_TYPE_FATALERR_BUF:
  2869. debug_info->name = "Fatal error (buff)";
  2870. debug_info->fatal_error.err_code1 = ex_info->content.fatalerr.error_code.code1;
  2871. debug_info->fatal_error.err_code2 = ex_info->content.fatalerr.error_code.code2;
  2872. break;
  2873. case MD_EX_TYPE_LOCKUP:
  2874. debug_info->name = "Lockup";
  2875. break;
  2876. case MD_EX_TYPE_ASSERT_DUMP:
  2877. debug_info->name = "ASSERT DUMP";
  2878. snprintf(debug_info->assert.file_name, sizeof(debug_info->assert.file_name),
  2879. ex_info->content.assert.filename);
  2880. debug_info->assert.line_num = ex_info->content.assert.linenumber;
  2881. break;
  2882. case DSP_EX_TYPE_ASSERT:
  2883. debug_info->name = "MD DMD ASSERT";
  2884. snprintf(debug_info->dsp_assert.file_name, sizeof(debug_info->dsp_assert.file_name),
  2885. ex_info->content.assert.filename);
  2886. debug_info->dsp_assert.line_num = ex_info->content.assert.linenumber;
  2887. snprintf(debug_info->dsp_assert.execution_unit, sizeof(debug_info->dsp_assert.execution_unit),
  2888. ex_info->envinfo.execution_unit);
  2889. debug_info->dsp_assert.parameters[0] = ex_info->content.assert.parameters[0];
  2890. debug_info->dsp_assert.parameters[1] = ex_info->content.assert.parameters[1];
  2891. debug_info->dsp_assert.parameters[2] = ex_info->content.assert.parameters[2];
  2892. break;
  2893. case DSP_EX_TYPE_EXCEPTION:
  2894. debug_info->name = "MD DMD Exception";
  2895. snprintf(debug_info->dsp_exception.execution_unit, sizeof(debug_info->dsp_exception.execution_unit),
  2896. ex_info->envinfo.execution_unit);
  2897. debug_info->dsp_exception.code1 = ex_info->content.fatalerr.error_code.code1;
  2898. break;
  2899. case DSP_EX_FATAL_ERROR:
  2900. debug_info->name = "MD DMD FATAL ERROR";
  2901. snprintf(debug_info->dsp_fatal_err.execution_unit, sizeof(debug_info->dsp_fatal_err.execution_unit),
  2902. ex_info->envinfo.execution_unit);
  2903. debug_info->dsp_fatal_err.err_code[0] = ex_info->content.fatalerr.error_code.code1;
  2904. debug_info->dsp_fatal_err.err_code[1] = ex_info->content.fatalerr.error_code.code2;
  2905. break;
  2906. default:
  2907. debug_info->name = "UNKNOWN Exception";
  2908. break;
  2909. }
  2910. debug_info->ext_mem = ex_info;
  2911. debug_info->ext_size = sizeof(EX_LOG_T);
  2912. debug_info->md_image = (void *)md->mem_layout.md_region_vir;
  2913. debug_info->md_size = MD_IMG_DUMP_SIZE;
  2914. }
  2915. void md_ex_monitor_func(unsigned long data)
  2916. {
  2917. int ee_on_going = 0;
  2918. int ee_case;
  2919. int need_update_state = 0;
  2920. unsigned long flags;
  2921. unsigned int ee_info_flag = 0;
  2922. struct ccci_modem *md = (struct ccci_modem *)data;
  2923. #if defined(CONFIG_MTK_AEE_FEATURE)
  2924. CCCI_NOTICE_MSG(md->index, KERN, "MD exception timer 1:disable tracing\n");
  2925. tracing_off();
  2926. #endif
  2927. CCCI_EXP_MSG(md->index, KERN, "MD exception timer 1! ee=%x\n", md->ee_info_flag);
  2928. spin_lock_irqsave(&md->ctrl_lock, flags);
  2929. if ((1 << MD_EE_DUMP_ON_GOING) & md->ee_info_flag) {
  2930. ee_on_going = 1;
  2931. } else {
  2932. ee_info_flag = md->ee_info_flag;
  2933. md->ee_info_flag |= (1 << MD_EE_DUMP_ON_GOING);
  2934. }
  2935. spin_unlock_irqrestore(&md->ctrl_lock, flags);
  2936. if (ee_on_going)
  2937. return;
  2938. if ((ee_info_flag & ((1 << MD_EE_MSG_GET) | (1 << MD_EE_OK_MSG_GET) | (1 << MD_EE_SWINT_GET))) ==
  2939. ((1 << MD_EE_MSG_GET) | (1 << MD_EE_OK_MSG_GET) | (1 << MD_EE_SWINT_GET))) {
  2940. ee_case = MD_EE_CASE_NORMAL;
  2941. CCCI_DBG_MSG(md->index, KERN, "Recv SWINT & MD_EX & MD_EX_REC_OK\n");
  2942. if (ee_info_flag & (1 << MD_EE_AP_MASK_I_BIT_TOO_LONG))
  2943. ee_case = MD_EE_CASE_AP_MASK_I_BIT_TOO_LONG;
  2944. } else if (!(ee_info_flag & (1 << MD_EE_SWINT_GET))
  2945. && (ee_info_flag & ((1 << MD_EE_MSG_GET) | (1 << MD_EE_OK_MSG_GET)))) {
  2946. ee_case = MD_EE_CASE_SWINT_MISSING;
  2947. CCCI_EXP_INF_MSG(md->index, KERN, "SWINT missing, ee_info_flag=%x\n", ee_info_flag);
  2948. } else if ((ee_info_flag & ((1 << MD_EE_MSG_GET) | (1 << MD_EE_SWINT_GET))) & (1 << MD_EE_MSG_GET)) {
  2949. ee_case = MD_EE_CASE_ONLY_EX;
  2950. CCCI_EXP_INF_MSG(md->index, KERN, "Only recv SWINT & MD_EX.\n");
  2951. if (ee_info_flag & (1 << MD_EE_AP_MASK_I_BIT_TOO_LONG))
  2952. ee_case = MD_EE_CASE_AP_MASK_I_BIT_TOO_LONG;
  2953. } else if ((ee_info_flag & ((1 << MD_EE_OK_MSG_GET) | (1 << MD_EE_SWINT_GET))) & (1 << MD_EE_OK_MSG_GET)) {
  2954. ee_case = MD_EE_CASE_ONLY_EX_OK;
  2955. CCCI_EXP_INF_MSG(md->index, KERN, "Only recv SWINT & MD_EX_OK\n");
  2956. if (ee_info_flag & (1 << MD_EE_AP_MASK_I_BIT_TOO_LONG))
  2957. ee_case = MD_EE_CASE_AP_MASK_I_BIT_TOO_LONG;
  2958. } else if (ee_info_flag & (1 << MD_EE_SWINT_GET)) {
  2959. ee_case = MD_EE_CASE_ONLY_SWINT;
  2960. CCCI_EXP_INF_MSG(md->index, KERN, "Only recv SWINT.\n");
  2961. if ((ee_info_flag & (1 << MD_STATE_UPDATE)) == 0)
  2962. need_update_state = 1;
  2963. } else if (ee_info_flag & (1 << MD_EE_AP_MASK_I_BIT_TOO_LONG)) {
  2964. ee_case = MD_EE_CASE_AP_MASK_I_BIT_TOO_LONG;
  2965. if ((ee_info_flag & (1 << MD_STATE_UPDATE)) == 0)
  2966. need_update_state = 1;
  2967. } else if (ee_info_flag & (1 << MD_EE_FOUND_BY_ISR)) {
  2968. ee_case = MD_EE_CASE_ISR_TRG;
  2969. if ((ee_info_flag & (1 << MD_STATE_UPDATE)) == 0)
  2970. need_update_state = 1;
  2971. } else if (ee_info_flag & (1 << MD_EE_FOUND_BY_TX)) {
  2972. ee_case = MD_EE_CASE_TX_TRG;
  2973. if ((ee_info_flag & (1 << MD_STATE_UPDATE)) == 0)
  2974. need_update_state = 1;
  2975. } else if (ee_info_flag & (1 << MD_EE_PENDING_TOO_LONG)) {
  2976. ee_case = MD_EE_CASE_NO_RESPONSE;
  2977. if ((ee_info_flag & (1 << MD_STATE_UPDATE)) == 0)
  2978. need_update_state = 1;
  2979. } else if (ee_info_flag & (1 << MD_EE_WDT_GET)) {
  2980. ee_case = MD_EE_CASE_WDT;
  2981. if ((ee_info_flag & (1 << MD_STATE_UPDATE)) == 0)
  2982. need_update_state = 1;
  2983. } else {
  2984. CCCI_EXP_MSG(md->index, KERN, "Invalid MD_EX, ee_info=%x\n", ee_info_flag);
  2985. goto _dump_done;
  2986. }
  2987. if (need_update_state) {
  2988. md->config.setting |= MD_SETTING_RELOAD;
  2989. md->ops->broadcast_state(md, EXCEPTION);
  2990. }
  2991. if (md->boot_stage < MD_BOOT_STAGE_2)
  2992. md->ops->broadcast_state(md, BOOT_FAIL);
  2993. /* ccci_send_virtual_md_msg(md, CCCI_MONITOR_CH, CCCI_MD_MSG_NOTIFY, ee_case); // unsafe in timer context */
  2994. md->debug_info.more_info = ee_case;
  2995. /* Dump MD EE info */
  2996. CCCI_EXP_INF_MSG(md->index, KERN, "Dump MD EX log\n");
  2997. #ifdef MD_UMOLY_EE_SUPPORT
  2998. if (md->index == MD_SYS1) {
  2999. ccci_mem_dump(md->index, md->smem_layout.ccci_exp_smem_mdss_debug_vir, (2048 + 512));
  3000. ccci_mem_dump(md->index, (md->smem_layout.ccci_exp_smem_mdss_debug_vir + 6 * 1024), 2048);
  3001. } else
  3002. #endif
  3003. ccci_mem_dump(md->index, md->smem_layout.ccci_exp_smem_base_vir, md->smem_layout.ccci_exp_dump_size);
  3004. /* Dump MD register */
  3005. md->ops->dump_info(md, DUMP_FLAG_REG, NULL, 0);
  3006. mod_timer(&md->ex_monitor2, jiffies + EX_TIMER_MD_EX_REC_OK * HZ);
  3007. _dump_done:
  3008. return;
  3009. }
  3010. EXPORT_SYMBOL(md_ex_monitor_func);
  3011. void md_ex_monitor2_func(unsigned long data)
  3012. {
  3013. struct ccci_modem *md = (struct ccci_modem *)data;
  3014. unsigned long flags;
  3015. int ee_on_going = 0;
  3016. CCCI_EXP_MSG(md->index, KERN, "MD exception timer 2! ee=%x\n", md->ee_info_flag);
  3017. spin_lock_irqsave(&md->ctrl_lock, flags);
  3018. if ((1 << MD_EE_TIMER2_DUMP_ON_GOING) & md->ee_info_flag)
  3019. ee_on_going = 1;
  3020. else
  3021. md->ee_info_flag |= (1 << MD_EE_TIMER2_DUMP_ON_GOING);
  3022. spin_unlock_irqrestore(&md->ctrl_lock, flags);
  3023. if (ee_on_going)
  3024. return;
  3025. #ifdef MD_UMOLY_EE_SUPPORT
  3026. if ((md->index == MD_SYS1)/* &&
  3027. !(md->debug_info.more_info == MD_EE_CASE_NORMAL && md->boot_stage == MD_BOOT_STAGE_0)*/) {
  3028. ccci_md_exp_change(md);
  3029. ccci_md_ee_info_dump(md);
  3030. } else {
  3031. #endif
  3032. ccci_md_exception(md);
  3033. ccci_ee_info_dump(md);
  3034. #ifdef MD_UMOLY_EE_SUPPORT
  3035. }
  3036. #endif
  3037. spin_lock_irqsave(&md->ctrl_lock, flags);
  3038. md->ee_info_flag = 0; /* this should be the last action of a regular exception flow,
  3039. clear flag for reset MD later */
  3040. spin_unlock_irqrestore(&md->ctrl_lock, flags);
  3041. CCCI_INF_MSG(md->index, KERN, "Enable WDT at exception exit.");
  3042. md->ops->ee_callback(md, EE_FLAG_ENABLE_WDT);
  3043. }
  3044. EXPORT_SYMBOL(md_ex_monitor2_func);
  3045. void md_bootup_timeout_func(unsigned long data)
  3046. {
  3047. struct ccci_modem *md = (struct ccci_modem *)data;
  3048. char ex_info[EE_BUF_LEN] = "";
  3049. CCCI_ERR_MSG(md->index, KERN, "MD_BOOT_HS%d_FAIL!\n", (md->boot_stage + 1));
  3050. md->ops->broadcast_state(md, BOOT_FAIL);
  3051. if (md->config.setting & MD_SETTING_STOP_RETRY_BOOT)
  3052. return;
  3053. /* ccci_send_virtual_md_msg(md, CCCI_MONITOR_CH, CCCI_MD_MSG_BOOT_TIMEOUT, 0); */
  3054. snprintf(ex_info, EE_BUF_LEN, "\n[Others] MD_BOOT_UP_FAIL(HS%d)\n", (md->boot_stage + 1));
  3055. CCCI_INF_MSG(md->index, KERN, "Dump MD image memory\n");
  3056. ccci_mem_dump(md->index, (void *)md->mem_layout.md_region_vir, MD_IMG_DUMP_SIZE);
  3057. CCCI_INF_MSG(md->index, KERN, "Dump MD layout struct\n");
  3058. ccci_mem_dump(md->index, &md->mem_layout, sizeof(struct ccci_mem_layout));
  3059. md->ops->dump_info(md, DUMP_FLAG_QUEUE_0_1, NULL, 0);
  3060. if (md->boot_stage == MD_BOOT_STAGE_0) {
  3061. /* Handshake 1 fail */
  3062. #ifdef MD_UMOLY_EE_SUPPORT
  3063. if (md->flight_mode) {
  3064. md->flight_mode = MD_FIGHT_MODE_NONE;
  3065. ccci_aed(md, CCCI_AED_DUMP_CCIF_REG | CCCI_AED_DUMP_MD_IMG_MEM | CCCI_AED_DUMP_EX_MEM,
  3066. ex_info, DB_OPT_DEFAULT);
  3067. } else
  3068. #endif
  3069. ccci_aed(md, CCCI_AED_DUMP_CCIF_REG | CCCI_AED_DUMP_MD_IMG_MEM, ex_info, DB_OPT_DEFAULT);
  3070. } else if (md->boot_stage == MD_BOOT_STAGE_1) {
  3071. /* Handshake 2 fail */
  3072. CCCI_INF_MSG(md->index, KERN, "Dump MD EX log\n");
  3073. ccci_mem_dump(md->index, md->smem_layout.ccci_exp_smem_base_vir, md->smem_layout.ccci_exp_dump_size);
  3074. ccci_aed(md, CCCI_AED_DUMP_CCIF_REG | CCCI_AED_DUMP_EX_MEM, ex_info, DB_OPT_FTRACE);
  3075. }
  3076. }
  3077. EXPORT_SYMBOL(md_bootup_timeout_func);
  3078. void ccci_subsys_kernel_init(void)
  3079. {
  3080. #ifdef FEATURE_GET_MD_EINT_ATTR_DTS
  3081. get_dtsi_eint_node();
  3082. #endif
  3083. debug_register_map();
  3084. }