Bcmchar.c 68 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652
  1. #include <linux/fs.h>
  2. #include "headers.h"
  3. static int bcm_handle_nvm_read_cmd(struct bcm_mini_adapter *ad,
  4. PUCHAR read_data,
  5. struct bcm_nvm_readwrite *nvm_rw)
  6. {
  7. INT status = STATUS_FAILURE;
  8. down(&ad->NVMRdmWrmLock);
  9. if ((ad->IdleMode == TRUE) || (ad->bShutStatus == TRUE) ||
  10. (ad->bPreparingForLowPowerMode == TRUE)) {
  11. BCM_DEBUG_PRINT(ad,
  12. DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  13. "Device is in Idle/Shutdown Mode\n");
  14. up(&ad->NVMRdmWrmLock);
  15. kfree(read_data);
  16. return -EACCES;
  17. }
  18. status = BeceemNVMRead(ad, (PUINT)read_data,
  19. nvm_rw->uiOffset,
  20. nvm_rw->uiNumBytes);
  21. up(&ad->NVMRdmWrmLock);
  22. if (status != STATUS_SUCCESS) {
  23. kfree(read_data);
  24. return status;
  25. }
  26. if (copy_to_user(nvm_rw->pBuffer, read_data, nvm_rw->uiNumBytes)) {
  27. kfree(read_data);
  28. return -EFAULT;
  29. }
  30. return STATUS_SUCCESS;
  31. }
  32. static int handle_flash2x_adapter(struct bcm_mini_adapter *ad,
  33. PUCHAR read_data,
  34. struct bcm_nvm_readwrite *nvm_rw)
  35. {
  36. /*
  37. * New Requirement:-
  38. * DSD section updation will be allowed in two case:-
  39. * 1. if DSD sig is present in DSD header means dongle
  40. * is ok and updation is fruitfull
  41. * 2. if point 1 failes then user buff should have
  42. * DSD sig. this point ensures that if dongle is
  43. * corrupted then user space program first modify
  44. * the DSD header with valid DSD sig so that this
  45. * as well as further write may be worthwhile.
  46. *
  47. * This restriction has been put assuming that
  48. * if DSD sig is corrupted, DSD data won't be
  49. * considered valid.
  50. */
  51. INT status;
  52. ULONG dsd_magic_num_in_usr_buff = 0;
  53. status = BcmFlash2xCorruptSig(ad, ad->eActiveDSD);
  54. if (status == STATUS_SUCCESS)
  55. return STATUS_SUCCESS;
  56. if (((nvm_rw->uiOffset + nvm_rw->uiNumBytes) !=
  57. ad->uiNVMDSDSize) ||
  58. (nvm_rw->uiNumBytes < SIGNATURE_SIZE)) {
  59. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  60. "DSD Sig is present neither in Flash nor User provided Input..");
  61. up(&ad->NVMRdmWrmLock);
  62. kfree(read_data);
  63. return status;
  64. }
  65. dsd_magic_num_in_usr_buff =
  66. ntohl(*(PUINT)(read_data + nvm_rw->uiNumBytes -
  67. SIGNATURE_SIZE));
  68. if (dsd_magic_num_in_usr_buff != DSD_IMAGE_MAGIC_NUMBER) {
  69. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  70. "DSD Sig is present neither in Flash nor User provided Input..");
  71. up(&ad->NVMRdmWrmLock);
  72. kfree(read_data);
  73. return status;
  74. }
  75. return STATUS_SUCCESS;
  76. }
  77. /***************************************************************
  78. * Function - bcm_char_open()
  79. *
  80. * Description - This is the "open" entry point for the character
  81. * driver.
  82. *
  83. * Parameters - inode: Pointer to the Inode structure of char device
  84. * filp : File pointer of the char device
  85. *
  86. * Returns - Zero(Success)
  87. ****************************************************************/
  88. static int bcm_char_open(struct inode *inode, struct file *filp)
  89. {
  90. struct bcm_mini_adapter *ad = NULL;
  91. struct bcm_tarang_data *tarang = NULL;
  92. ad = GET_BCM_ADAPTER(gblpnetdev);
  93. tarang = kzalloc(sizeof(struct bcm_tarang_data), GFP_KERNEL);
  94. if (!tarang)
  95. return -ENOMEM;
  96. tarang->Adapter = ad;
  97. tarang->RxCntrlMsgBitMask = 0xFFFFFFFF & ~(1 << 0xB);
  98. down(&ad->RxAppControlQueuelock);
  99. tarang->next = ad->pTarangs;
  100. ad->pTarangs = tarang;
  101. up(&ad->RxAppControlQueuelock);
  102. /* Store the Adapter structure */
  103. filp->private_data = tarang;
  104. /* Start Queuing the control response Packets */
  105. atomic_inc(&ad->ApplicationRunning);
  106. nonseekable_open(inode, filp);
  107. return 0;
  108. }
  109. static int bcm_char_release(struct inode *inode, struct file *filp)
  110. {
  111. struct bcm_tarang_data *tarang, *tmp, *ptmp;
  112. struct bcm_mini_adapter *ad = NULL;
  113. struct sk_buff *pkt, *npkt;
  114. tarang = (struct bcm_tarang_data *)filp->private_data;
  115. if (tarang == NULL)
  116. return 0;
  117. ad = tarang->Adapter;
  118. down(&ad->RxAppControlQueuelock);
  119. tmp = ad->pTarangs;
  120. for (ptmp = NULL; tmp; ptmp = tmp, tmp = tmp->next) {
  121. if (tmp == tarang)
  122. break;
  123. }
  124. if (tmp) {
  125. if (!ptmp)
  126. ad->pTarangs = tmp->next;
  127. else
  128. ptmp->next = tmp->next;
  129. } else {
  130. up(&ad->RxAppControlQueuelock);
  131. return 0;
  132. }
  133. pkt = tarang->RxAppControlHead;
  134. while (pkt) {
  135. npkt = pkt->next;
  136. kfree_skb(pkt);
  137. pkt = npkt;
  138. }
  139. up(&ad->RxAppControlQueuelock);
  140. /* Stop Queuing the control response Packets */
  141. atomic_dec(&ad->ApplicationRunning);
  142. kfree(tarang);
  143. /* remove this filp from the asynchronously notified filp's */
  144. filp->private_data = NULL;
  145. return 0;
  146. }
  147. static ssize_t bcm_char_read(struct file *filp,
  148. char __user *buf,
  149. size_t size,
  150. loff_t *f_pos)
  151. {
  152. struct bcm_tarang_data *tarang = filp->private_data;
  153. struct bcm_mini_adapter *ad = tarang->Adapter;
  154. struct sk_buff *packet = NULL;
  155. ssize_t pkt_len = 0;
  156. int wait_ret_val = 0;
  157. unsigned long ret = 0;
  158. wait_ret_val = wait_event_interruptible(
  159. ad->process_read_wait_queue,
  160. (tarang->RxAppControlHead ||
  161. ad->device_removed));
  162. if ((wait_ret_val == -ERESTARTSYS)) {
  163. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  164. "Exiting as i've been asked to exit!!!\n");
  165. return wait_ret_val;
  166. }
  167. if (ad->device_removed) {
  168. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  169. "Device Removed... Killing the Apps...\n");
  170. return -ENODEV;
  171. }
  172. if (false == ad->fw_download_done)
  173. return -EACCES;
  174. down(&ad->RxAppControlQueuelock);
  175. if (tarang->RxAppControlHead) {
  176. packet = tarang->RxAppControlHead;
  177. DEQUEUEPACKET(tarang->RxAppControlHead,
  178. tarang->RxAppControlTail);
  179. tarang->AppCtrlQueueLen--;
  180. }
  181. up(&ad->RxAppControlQueuelock);
  182. if (packet) {
  183. pkt_len = packet->len;
  184. ret = copy_to_user(buf, packet->data,
  185. min_t(size_t, pkt_len, size));
  186. if (ret) {
  187. dev_kfree_skb(packet);
  188. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  189. "Returning from copy to user failure\n");
  190. return -EFAULT;
  191. }
  192. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  193. "Read %zd Bytes From Adapter packet = %p by process %d!\n",
  194. pkt_len, packet, current->pid);
  195. dev_kfree_skb(packet);
  196. }
  197. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "<\n");
  198. return pkt_len;
  199. }
  200. static int bcm_char_ioctl_reg_read_private(void __user *argp,
  201. struct bcm_mini_adapter *ad)
  202. {
  203. struct bcm_rdm_buffer rdm_buff = {0};
  204. struct bcm_ioctl_buffer io_buff;
  205. PCHAR temp_buff;
  206. INT status = STATUS_FAILURE;
  207. UINT buff_len;
  208. u16 temp_value;
  209. int bytes;
  210. /* Copy Ioctl Buffer structure */
  211. if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer)))
  212. return -EFAULT;
  213. if (io_buff.InputLength > sizeof(rdm_buff))
  214. return -EINVAL;
  215. if (copy_from_user(&rdm_buff, io_buff.InputBuffer,
  216. io_buff.InputLength))
  217. return -EFAULT;
  218. if (io_buff.OutputLength > USHRT_MAX ||
  219. io_buff.OutputLength == 0) {
  220. return -EINVAL;
  221. }
  222. buff_len = io_buff.OutputLength;
  223. temp_value = 4 - (buff_len % 4);
  224. buff_len += temp_value % 4;
  225. temp_buff = kmalloc(buff_len, GFP_KERNEL);
  226. if (!temp_buff)
  227. return -ENOMEM;
  228. bytes = rdmalt(ad, (UINT)rdm_buff.Register,
  229. (PUINT)temp_buff, buff_len);
  230. if (bytes > 0) {
  231. status = STATUS_SUCCESS;
  232. if (copy_to_user(io_buff.OutputBuffer, temp_buff, bytes)) {
  233. kfree(temp_buff);
  234. return -EFAULT;
  235. }
  236. } else {
  237. status = bytes;
  238. }
  239. kfree(temp_buff);
  240. return status;
  241. }
  242. static int bcm_char_ioctl_reg_write_private(void __user *argp,
  243. struct bcm_mini_adapter *ad)
  244. {
  245. struct bcm_wrm_buffer wrm_buff = {0};
  246. struct bcm_ioctl_buffer io_buff;
  247. UINT tmp = 0;
  248. INT status;
  249. /* Copy Ioctl Buffer structure */
  250. if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer)))
  251. return -EFAULT;
  252. if (io_buff.InputLength > sizeof(wrm_buff))
  253. return -EINVAL;
  254. /* Get WrmBuffer structure */
  255. if (copy_from_user(&wrm_buff, io_buff.InputBuffer,
  256. io_buff.InputLength))
  257. return -EFAULT;
  258. tmp = wrm_buff.Register & EEPROM_REJECT_MASK;
  259. if (!((ad->pstargetparams->m_u32Customize) & VSG_MODE) &&
  260. ((tmp == EEPROM_REJECT_REG_1) ||
  261. (tmp == EEPROM_REJECT_REG_2) ||
  262. (tmp == EEPROM_REJECT_REG_3) ||
  263. (tmp == EEPROM_REJECT_REG_4))) {
  264. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  265. "EEPROM Access Denied, not in VSG Mode\n");
  266. return -EFAULT;
  267. }
  268. status = wrmalt(ad, (UINT)wrm_buff.Register,
  269. (PUINT)wrm_buff.Data, sizeof(ULONG));
  270. if (status == STATUS_SUCCESS) {
  271. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG,
  272. DBG_LVL_ALL, "WRM Done\n");
  273. } else {
  274. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG,
  275. DBG_LVL_ALL, "WRM Failed\n");
  276. status = -EFAULT;
  277. }
  278. return status;
  279. }
  280. static int bcm_char_ioctl_eeprom_reg_read(void __user *argp,
  281. struct bcm_mini_adapter *ad)
  282. {
  283. struct bcm_rdm_buffer rdm_buff = {0};
  284. struct bcm_ioctl_buffer io_buff;
  285. PCHAR temp_buff = NULL;
  286. UINT tmp = 0;
  287. INT status;
  288. int bytes;
  289. if ((ad->IdleMode == TRUE) ||
  290. (ad->bShutStatus == TRUE) ||
  291. (ad->bPreparingForLowPowerMode == TRUE)) {
  292. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  293. "Device in Idle Mode, Blocking Rdms\n");
  294. return -EACCES;
  295. }
  296. /* Copy Ioctl Buffer structure */
  297. if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer)))
  298. return -EFAULT;
  299. if (io_buff.InputLength > sizeof(rdm_buff))
  300. return -EINVAL;
  301. if (copy_from_user(&rdm_buff, io_buff.InputBuffer,
  302. io_buff.InputLength))
  303. return -EFAULT;
  304. if (io_buff.OutputLength > USHRT_MAX ||
  305. io_buff.OutputLength == 0) {
  306. return -EINVAL;
  307. }
  308. temp_buff = kmalloc(io_buff.OutputLength, GFP_KERNEL);
  309. if (!temp_buff)
  310. return STATUS_FAILURE;
  311. if ((((ULONG)rdm_buff.Register & 0x0F000000) != 0x0F000000) ||
  312. ((ULONG)rdm_buff.Register & 0x3)) {
  313. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  314. "RDM Done On invalid Address : %x Access Denied.\n",
  315. (int)rdm_buff.Register);
  316. kfree(temp_buff);
  317. return -EINVAL;
  318. }
  319. tmp = rdm_buff.Register & EEPROM_REJECT_MASK;
  320. bytes = rdmaltWithLock(ad, (UINT)rdm_buff.Register,
  321. (PUINT)temp_buff, io_buff.OutputLength);
  322. if (bytes > 0) {
  323. status = STATUS_SUCCESS;
  324. if (copy_to_user(io_buff.OutputBuffer, temp_buff, bytes)) {
  325. kfree(temp_buff);
  326. return -EFAULT;
  327. }
  328. } else {
  329. status = bytes;
  330. }
  331. kfree(temp_buff);
  332. return status;
  333. }
  334. static int bcm_char_ioctl_eeprom_reg_write(void __user *argp,
  335. struct bcm_mini_adapter *ad,
  336. UINT cmd)
  337. {
  338. struct bcm_wrm_buffer wrm_buff = {0};
  339. struct bcm_ioctl_buffer io_buff;
  340. UINT tmp = 0;
  341. INT status;
  342. if ((ad->IdleMode == TRUE) ||
  343. (ad->bShutStatus == TRUE) ||
  344. (ad->bPreparingForLowPowerMode == TRUE)) {
  345. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  346. "Device in Idle Mode, Blocking Wrms\n");
  347. return -EACCES;
  348. }
  349. /* Copy Ioctl Buffer structure */
  350. if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer)))
  351. return -EFAULT;
  352. if (io_buff.InputLength > sizeof(wrm_buff))
  353. return -EINVAL;
  354. /* Get WrmBuffer structure */
  355. if (copy_from_user(&wrm_buff, io_buff.InputBuffer,
  356. io_buff.InputLength))
  357. return -EFAULT;
  358. if ((((ULONG)wrm_buff.Register & 0x0F000000) != 0x0F000000) ||
  359. ((ULONG)wrm_buff.Register & 0x3)) {
  360. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  361. "WRM Done On invalid Address : %x Access Denied.\n",
  362. (int)wrm_buff.Register);
  363. return -EINVAL;
  364. }
  365. tmp = wrm_buff.Register & EEPROM_REJECT_MASK;
  366. if (!((ad->pstargetparams->m_u32Customize) & VSG_MODE) &&
  367. ((tmp == EEPROM_REJECT_REG_1) ||
  368. (tmp == EEPROM_REJECT_REG_2) ||
  369. (tmp == EEPROM_REJECT_REG_3) ||
  370. (tmp == EEPROM_REJECT_REG_4)) &&
  371. (cmd == IOCTL_BCM_REGISTER_WRITE)) {
  372. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  373. "EEPROM Access Denied, not in VSG Mode\n");
  374. return -EFAULT;
  375. }
  376. status = wrmaltWithLock(ad, (UINT)wrm_buff.Register,
  377. (PUINT)wrm_buff.Data,
  378. wrm_buff.Length);
  379. if (status == STATUS_SUCCESS) {
  380. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, OSAL_DBG,
  381. DBG_LVL_ALL, "WRM Done\n");
  382. } else {
  383. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG,
  384. DBG_LVL_ALL, "WRM Failed\n");
  385. status = -EFAULT;
  386. }
  387. return status;
  388. }
  389. static int bcm_char_ioctl_gpio_set_request(void __user *argp,
  390. struct bcm_mini_adapter *ad)
  391. {
  392. struct bcm_gpio_info gpio_info = {0};
  393. struct bcm_ioctl_buffer io_buff;
  394. UCHAR reset_val[4];
  395. UINT value = 0;
  396. UINT bit = 0;
  397. UINT operation = 0;
  398. INT status;
  399. int bytes;
  400. if ((ad->IdleMode == TRUE) ||
  401. (ad->bShutStatus == TRUE) ||
  402. (ad->bPreparingForLowPowerMode == TRUE)) {
  403. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG,
  404. DBG_LVL_ALL,
  405. "GPIO Can't be set/clear in Low power Mode");
  406. return -EACCES;
  407. }
  408. if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer)))
  409. return -EFAULT;
  410. if (io_buff.InputLength > sizeof(gpio_info))
  411. return -EINVAL;
  412. if (copy_from_user(&gpio_info, io_buff.InputBuffer,
  413. io_buff.InputLength))
  414. return -EFAULT;
  415. bit = gpio_info.uiGpioNumber;
  416. operation = gpio_info.uiGpioValue;
  417. value = (1<<bit);
  418. if (IsReqGpioIsLedInNVM(ad, value) == false) {
  419. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG,
  420. DBG_LVL_ALL,
  421. "Sorry, Requested GPIO<0x%X> is not correspond to LED !!!",
  422. value);
  423. return -EINVAL;
  424. }
  425. /* Set - setting 1 */
  426. if (operation) {
  427. /* Set the gpio output register */
  428. status = wrmaltWithLock(ad,
  429. BCM_GPIO_OUTPUT_SET_REG,
  430. (PUINT)(&value), sizeof(UINT));
  431. if (status == STATUS_SUCCESS) {
  432. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS,
  433. OSAL_DBG, DBG_LVL_ALL,
  434. "Set the GPIO bit\n");
  435. } else {
  436. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS,
  437. OSAL_DBG, DBG_LVL_ALL,
  438. "Failed to set the %dth GPIO\n",
  439. bit);
  440. return status;
  441. }
  442. } else {
  443. /* Set the gpio output register */
  444. status = wrmaltWithLock(ad,
  445. BCM_GPIO_OUTPUT_CLR_REG,
  446. (PUINT)(&value), sizeof(UINT));
  447. if (status == STATUS_SUCCESS) {
  448. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS,
  449. OSAL_DBG, DBG_LVL_ALL,
  450. "Set the GPIO bit\n");
  451. } else {
  452. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS,
  453. OSAL_DBG, DBG_LVL_ALL,
  454. "Failed to clear the %dth GPIO\n",
  455. bit);
  456. return status;
  457. }
  458. }
  459. bytes = rdmaltWithLock(ad, (UINT)GPIO_MODE_REGISTER,
  460. (PUINT)reset_val, sizeof(UINT));
  461. if (bytes < 0) {
  462. status = bytes;
  463. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  464. "GPIO_MODE_REGISTER read failed");
  465. return status;
  466. }
  467. status = STATUS_SUCCESS;
  468. /* Set the gpio mode register to output */
  469. *(UINT *)reset_val |= (1<<bit);
  470. status = wrmaltWithLock(ad, GPIO_MODE_REGISTER,
  471. (PUINT)reset_val, sizeof(UINT));
  472. if (status == STATUS_SUCCESS) {
  473. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG,
  474. DBG_LVL_ALL,
  475. "Set the GPIO to output Mode\n");
  476. } else {
  477. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG,
  478. DBG_LVL_ALL,
  479. "Failed to put GPIO in Output Mode\n");
  480. }
  481. return status;
  482. }
  483. static int bcm_char_ioctl_led_thread_state_change_req(void __user *argp,
  484. struct bcm_mini_adapter *ad)
  485. {
  486. struct bcm_user_thread_req thread_req = {0};
  487. struct bcm_ioctl_buffer io_buff;
  488. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  489. "User made LED thread InActive");
  490. if ((ad->IdleMode == TRUE) ||
  491. (ad->bShutStatus == TRUE) ||
  492. (ad->bPreparingForLowPowerMode == TRUE)) {
  493. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG,
  494. DBG_LVL_ALL,
  495. "GPIO Can't be set/clear in Low power Mode");
  496. return -EACCES;
  497. }
  498. if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer)))
  499. return -EFAULT;
  500. if (io_buff.InputLength > sizeof(thread_req))
  501. return -EINVAL;
  502. if (copy_from_user(&thread_req, io_buff.InputBuffer,
  503. io_buff.InputLength))
  504. return -EFAULT;
  505. /* if LED thread is running(Actively or Inactively)
  506. * set it state to make inactive
  507. */
  508. if (ad->LEDInfo.led_thread_running) {
  509. if (thread_req.ThreadState == LED_THREAD_ACTIVATION_REQ) {
  510. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS,
  511. OSAL_DBG, DBG_LVL_ALL,
  512. "Activating thread req");
  513. ad->DriverState = LED_THREAD_ACTIVE;
  514. } else {
  515. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS,
  516. OSAL_DBG, DBG_LVL_ALL,
  517. "DeActivating Thread req.....");
  518. ad->DriverState = LED_THREAD_INACTIVE;
  519. }
  520. /* signal thread. */
  521. wake_up(&ad->LEDInfo.notify_led_event);
  522. }
  523. return STATUS_SUCCESS;
  524. }
  525. static int bcm_char_ioctl_gpio_status_request(void __user *argp,
  526. struct bcm_mini_adapter *ad)
  527. {
  528. struct bcm_gpio_info gpio_info = {0};
  529. struct bcm_ioctl_buffer io_buff;
  530. ULONG bit = 0;
  531. UCHAR read[4];
  532. INT status;
  533. int bytes;
  534. if ((ad->IdleMode == TRUE) ||
  535. (ad->bShutStatus == TRUE) ||
  536. (ad->bPreparingForLowPowerMode == TRUE))
  537. return -EACCES;
  538. if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer)))
  539. return -EFAULT;
  540. if (io_buff.InputLength > sizeof(gpio_info))
  541. return -EINVAL;
  542. if (copy_from_user(&gpio_info, io_buff.InputBuffer,
  543. io_buff.InputLength))
  544. return -EFAULT;
  545. bit = gpio_info.uiGpioNumber;
  546. /* Set the gpio output register */
  547. bytes = rdmaltWithLock(ad, (UINT)GPIO_PIN_STATE_REGISTER,
  548. (PUINT)read, sizeof(UINT));
  549. if (bytes < 0) {
  550. status = bytes;
  551. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  552. "RDM Failed\n");
  553. return status;
  554. }
  555. status = STATUS_SUCCESS;
  556. return status;
  557. }
  558. static int bcm_char_ioctl_gpio_multi_request(void __user *argp,
  559. struct bcm_mini_adapter *ad)
  560. {
  561. struct bcm_gpio_multi_info gpio_multi_info[MAX_IDX];
  562. struct bcm_gpio_multi_info *pgpio_multi_info =
  563. (struct bcm_gpio_multi_info *)gpio_multi_info;
  564. struct bcm_ioctl_buffer io_buff;
  565. UCHAR reset_val[4];
  566. INT status = STATUS_FAILURE;
  567. int bytes;
  568. memset(pgpio_multi_info, 0,
  569. MAX_IDX * sizeof(struct bcm_gpio_multi_info));
  570. if ((ad->IdleMode == TRUE) ||
  571. (ad->bShutStatus == TRUE) ||
  572. (ad->bPreparingForLowPowerMode == TRUE))
  573. return -EINVAL;
  574. if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer)))
  575. return -EFAULT;
  576. if (io_buff.InputLength > sizeof(gpio_multi_info))
  577. return -EINVAL;
  578. if (io_buff.OutputLength > sizeof(gpio_multi_info))
  579. io_buff.OutputLength = sizeof(gpio_multi_info);
  580. if (copy_from_user(&gpio_multi_info, io_buff.InputBuffer,
  581. io_buff.InputLength))
  582. return -EFAULT;
  583. if (IsReqGpioIsLedInNVM(ad, pgpio_multi_info[WIMAX_IDX].uiGPIOMask)
  584. == false) {
  585. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG,
  586. DBG_LVL_ALL,
  587. "Sorry, Requested GPIO<0x%X> is not correspond to NVM LED bit map<0x%X>!!!",
  588. pgpio_multi_info[WIMAX_IDX].uiGPIOMask,
  589. ad->gpioBitMap);
  590. return -EINVAL;
  591. }
  592. /* Set the gpio output register */
  593. if ((pgpio_multi_info[WIMAX_IDX].uiGPIOMask) &
  594. (pgpio_multi_info[WIMAX_IDX].uiGPIOCommand)) {
  595. /* Set 1's in GPIO OUTPUT REGISTER */
  596. *(UINT *)reset_val = pgpio_multi_info[WIMAX_IDX].uiGPIOMask &
  597. pgpio_multi_info[WIMAX_IDX].uiGPIOCommand &
  598. pgpio_multi_info[WIMAX_IDX].uiGPIOValue;
  599. if (*(UINT *) reset_val)
  600. status = wrmaltWithLock(ad,
  601. BCM_GPIO_OUTPUT_SET_REG,
  602. (PUINT)reset_val, sizeof(ULONG));
  603. if (status != STATUS_SUCCESS) {
  604. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  605. "WRM to BCM_GPIO_OUTPUT_SET_REG Failed.");
  606. return status;
  607. }
  608. /* Clear to 0's in GPIO OUTPUT REGISTER */
  609. *(UINT *)reset_val =
  610. (pgpio_multi_info[WIMAX_IDX].uiGPIOMask &
  611. pgpio_multi_info[WIMAX_IDX].uiGPIOCommand &
  612. (~(pgpio_multi_info[WIMAX_IDX].uiGPIOValue)));
  613. if (*(UINT *) reset_val)
  614. status = wrmaltWithLock(ad,
  615. BCM_GPIO_OUTPUT_CLR_REG, (PUINT)reset_val,
  616. sizeof(ULONG));
  617. if (status != STATUS_SUCCESS) {
  618. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  619. "WRM to BCM_GPIO_OUTPUT_CLR_REG Failed.");
  620. return status;
  621. }
  622. }
  623. if (pgpio_multi_info[WIMAX_IDX].uiGPIOMask) {
  624. bytes = rdmaltWithLock(ad, (UINT)GPIO_PIN_STATE_REGISTER,
  625. (PUINT)reset_val, sizeof(UINT));
  626. if (bytes < 0) {
  627. status = bytes;
  628. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  629. "RDM to GPIO_PIN_STATE_REGISTER Failed.");
  630. return status;
  631. }
  632. status = STATUS_SUCCESS;
  633. pgpio_multi_info[WIMAX_IDX].uiGPIOValue =
  634. (*(UINT *)reset_val &
  635. pgpio_multi_info[WIMAX_IDX].uiGPIOMask);
  636. }
  637. status = copy_to_user(io_buff.OutputBuffer, &gpio_multi_info,
  638. io_buff.OutputLength);
  639. if (status) {
  640. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  641. "Failed while copying Content to IOBufer for user space err:%d",
  642. status);
  643. return -EFAULT;
  644. }
  645. return status;
  646. }
  647. static int bcm_char_ioctl_gpio_mode_request(void __user *argp,
  648. struct bcm_mini_adapter *ad)
  649. {
  650. struct bcm_gpio_multi_mode gpio_multi_mode[MAX_IDX];
  651. struct bcm_gpio_multi_mode *pgpio_multi_mode =
  652. (struct bcm_gpio_multi_mode *)gpio_multi_mode;
  653. struct bcm_ioctl_buffer io_buff;
  654. UCHAR reset_val[4];
  655. INT status;
  656. int bytes;
  657. if ((ad->IdleMode == TRUE) ||
  658. (ad->bShutStatus == TRUE) ||
  659. (ad->bPreparingForLowPowerMode == TRUE))
  660. return -EINVAL;
  661. if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer)))
  662. return -EFAULT;
  663. if (io_buff.InputLength > sizeof(gpio_multi_mode))
  664. return -EINVAL;
  665. if (io_buff.OutputLength > sizeof(gpio_multi_mode))
  666. io_buff.OutputLength = sizeof(gpio_multi_mode);
  667. if (copy_from_user(&gpio_multi_mode, io_buff.InputBuffer,
  668. io_buff.InputLength))
  669. return -EFAULT;
  670. bytes = rdmaltWithLock(ad, (UINT)GPIO_MODE_REGISTER,
  671. (PUINT)reset_val, sizeof(UINT));
  672. if (bytes < 0) {
  673. status = bytes;
  674. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  675. "Read of GPIO_MODE_REGISTER failed");
  676. return status;
  677. }
  678. status = STATUS_SUCCESS;
  679. /* Validating the request */
  680. if (IsReqGpioIsLedInNVM(ad, pgpio_multi_mode[WIMAX_IDX].uiGPIOMask)
  681. == false) {
  682. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  683. "Sorry, Requested GPIO<0x%X> is not correspond to NVM LED bit map<0x%X>!!!",
  684. pgpio_multi_mode[WIMAX_IDX].uiGPIOMask,
  685. ad->gpioBitMap);
  686. return -EINVAL;
  687. }
  688. if (pgpio_multi_mode[WIMAX_IDX].uiGPIOMask) {
  689. /* write all OUT's (1's) */
  690. *(UINT *) reset_val |=
  691. (pgpio_multi_mode[WIMAX_IDX].uiGPIOMode &
  692. pgpio_multi_mode[WIMAX_IDX].uiGPIOMask);
  693. /* write all IN's (0's) */
  694. *(UINT *) reset_val &=
  695. ~((~pgpio_multi_mode[WIMAX_IDX].uiGPIOMode) &
  696. pgpio_multi_mode[WIMAX_IDX].uiGPIOMask);
  697. /* Currently implemented return the modes of all GPIO's
  698. * else needs to bit AND with mask
  699. */
  700. pgpio_multi_mode[WIMAX_IDX].uiGPIOMode = *(UINT *)reset_val;
  701. status = wrmaltWithLock(ad, GPIO_MODE_REGISTER,
  702. (PUINT)reset_val, sizeof(ULONG));
  703. if (status == STATUS_SUCCESS) {
  704. BCM_DEBUG_PRINT(ad,
  705. DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  706. "WRM to GPIO_MODE_REGISTER Done");
  707. } else {
  708. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  709. "WRM to GPIO_MODE_REGISTER Failed");
  710. return -EFAULT;
  711. }
  712. } else {
  713. /* if uiGPIOMask is 0 then return mode register configuration */
  714. pgpio_multi_mode[WIMAX_IDX].uiGPIOMode = *(UINT *)reset_val;
  715. }
  716. status = copy_to_user(io_buff.OutputBuffer, &gpio_multi_mode,
  717. io_buff.OutputLength);
  718. if (status) {
  719. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  720. "Failed while copying Content to IOBufer for user space err:%d",
  721. status);
  722. return -EFAULT;
  723. }
  724. return status;
  725. }
  726. static int bcm_char_ioctl_misc_request(void __user *argp,
  727. struct bcm_mini_adapter *ad)
  728. {
  729. struct bcm_ioctl_buffer io_buff;
  730. PVOID buff = NULL;
  731. INT status;
  732. /* Copy Ioctl Buffer structure */
  733. if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer)))
  734. return -EFAULT;
  735. if (io_buff.InputLength < sizeof(struct bcm_link_request))
  736. return -EINVAL;
  737. if (io_buff.InputLength > MAX_CNTL_PKT_SIZE)
  738. return -EINVAL;
  739. buff = memdup_user(io_buff.InputBuffer,
  740. io_buff.InputLength);
  741. if (IS_ERR(buff))
  742. return PTR_ERR(buff);
  743. down(&ad->LowPowerModeSync);
  744. status = wait_event_interruptible_timeout(
  745. ad->lowpower_mode_wait_queue,
  746. !ad->bPreparingForLowPowerMode,
  747. (1 * HZ));
  748. if (status == -ERESTARTSYS)
  749. goto cntrlEnd;
  750. if (ad->bPreparingForLowPowerMode) {
  751. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  752. "Preparing Idle Mode is still True - Hence Rejecting control message\n");
  753. status = STATUS_FAILURE;
  754. goto cntrlEnd;
  755. }
  756. status = CopyBufferToControlPacket(ad, (PVOID)buff);
  757. cntrlEnd:
  758. up(&ad->LowPowerModeSync);
  759. kfree(buff);
  760. return status;
  761. }
  762. static int bcm_char_ioctl_buffer_download_start(
  763. struct bcm_mini_adapter *ad)
  764. {
  765. INT status;
  766. if (down_trylock(&ad->NVMRdmWrmLock)) {
  767. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  768. "IOCTL_BCM_CHIP_RESET not allowed as EEPROM Read/Write is in progress\n");
  769. return -EACCES;
  770. }
  771. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  772. "Starting the firmware download PID =0x%x!!!!\n",
  773. current->pid);
  774. if (down_trylock(&ad->fw_download_sema))
  775. return -EBUSY;
  776. ad->bBinDownloaded = false;
  777. ad->fw_download_process_pid = current->pid;
  778. ad->bCfgDownloaded = false;
  779. ad->fw_download_done = false;
  780. netif_carrier_off(ad->dev);
  781. netif_stop_queue(ad->dev);
  782. status = reset_card_proc(ad);
  783. if (status) {
  784. pr_err(PFX "%s: reset_card_proc Failed!\n", ad->dev->name);
  785. up(&ad->fw_download_sema);
  786. up(&ad->NVMRdmWrmLock);
  787. return status;
  788. }
  789. mdelay(10);
  790. up(&ad->NVMRdmWrmLock);
  791. return status;
  792. }
  793. static int bcm_char_ioctl_buffer_download(void __user *argp,
  794. struct bcm_mini_adapter *ad)
  795. {
  796. struct bcm_firmware_info *fw_info = NULL;
  797. struct bcm_ioctl_buffer io_buff;
  798. INT status;
  799. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  800. "Starting the firmware download PID =0x%x!!!!\n", current->pid);
  801. if (!down_trylock(&ad->fw_download_sema)) {
  802. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  803. "Invalid way to download buffer. Use Start and then call this!!!\n");
  804. up(&ad->fw_download_sema);
  805. return -EINVAL;
  806. }
  807. /* Copy Ioctl Buffer structure */
  808. if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) {
  809. up(&ad->fw_download_sema);
  810. return -EFAULT;
  811. }
  812. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  813. "Length for FW DLD is : %lx\n", io_buff.InputLength);
  814. if (io_buff.InputLength > sizeof(struct bcm_firmware_info)) {
  815. up(&ad->fw_download_sema);
  816. return -EINVAL;
  817. }
  818. fw_info = kmalloc(sizeof(*fw_info), GFP_KERNEL);
  819. if (!fw_info) {
  820. up(&ad->fw_download_sema);
  821. return -ENOMEM;
  822. }
  823. if (copy_from_user(fw_info, io_buff.InputBuffer,
  824. io_buff.InputLength)) {
  825. up(&ad->fw_download_sema);
  826. kfree(fw_info);
  827. return -EFAULT;
  828. }
  829. if (!fw_info->pvMappedFirmwareAddress ||
  830. (fw_info->u32FirmwareLength == 0)) {
  831. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  832. "Something else is wrong %lu\n",
  833. fw_info->u32FirmwareLength);
  834. up(&ad->fw_download_sema);
  835. kfree(fw_info);
  836. status = -EINVAL;
  837. return status;
  838. }
  839. status = bcm_ioctl_fw_download(ad, fw_info);
  840. if (status != STATUS_SUCCESS) {
  841. if (fw_info->u32StartingAddress == CONFIG_BEGIN_ADDR)
  842. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  843. "IOCTL: Configuration File Upload Failed\n");
  844. else
  845. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  846. "IOCTL: Firmware File Upload Failed\n");
  847. /* up(&ad->fw_download_sema); */
  848. if (ad->LEDInfo.led_thread_running &
  849. BCM_LED_THREAD_RUNNING_ACTIVELY) {
  850. ad->DriverState = DRIVER_INIT;
  851. ad->LEDInfo.bLedInitDone = false;
  852. wake_up(&ad->LEDInfo.notify_led_event);
  853. }
  854. }
  855. if (status != STATUS_SUCCESS)
  856. up(&ad->fw_download_sema);
  857. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, OSAL_DBG, DBG_LVL_ALL,
  858. "IOCTL: Firmware File Uploaded\n");
  859. kfree(fw_info);
  860. return status;
  861. }
  862. static int bcm_char_ioctl_buffer_download_stop(void __user *argp,
  863. struct bcm_mini_adapter *ad)
  864. {
  865. INT status;
  866. int timeout = 0;
  867. if (!down_trylock(&ad->fw_download_sema)) {
  868. up(&ad->fw_download_sema);
  869. return -EINVAL;
  870. }
  871. if (down_trylock(&ad->NVMRdmWrmLock)) {
  872. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  873. "FW download blocked as EEPROM Read/Write is in progress\n");
  874. up(&ad->fw_download_sema);
  875. return -EACCES;
  876. }
  877. ad->bBinDownloaded = TRUE;
  878. ad->bCfgDownloaded = TRUE;
  879. atomic_set(&ad->CurrNumFreeTxDesc, 0);
  880. ad->CurrNumRecvDescs = 0;
  881. ad->downloadDDR = 0;
  882. /* setting the Mips to Run */
  883. status = run_card_proc(ad);
  884. if (status) {
  885. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  886. "Firm Download Failed\n");
  887. up(&ad->fw_download_sema);
  888. up(&ad->NVMRdmWrmLock);
  889. return status;
  890. }
  891. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG,
  892. DBG_LVL_ALL, "Firm Download Over...\n");
  893. mdelay(10);
  894. /* Wait for MailBox Interrupt */
  895. if (StartInterruptUrb((struct bcm_interface_adapter *)ad->pvInterfaceAdapter))
  896. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  897. "Unable to send interrupt...\n");
  898. timeout = 5*HZ;
  899. ad->waiting_to_fw_download_done = false;
  900. wait_event_timeout(ad->ioctl_fw_dnld_wait_queue,
  901. ad->waiting_to_fw_download_done, timeout);
  902. ad->fw_download_process_pid = INVALID_PID;
  903. ad->fw_download_done = TRUE;
  904. atomic_set(&ad->CurrNumFreeTxDesc, 0);
  905. ad->CurrNumRecvDescs = 0;
  906. ad->PrevNumRecvDescs = 0;
  907. atomic_set(&ad->cntrlpktCnt, 0);
  908. ad->LinkUpStatus = 0;
  909. ad->LinkStatus = 0;
  910. if (ad->LEDInfo.led_thread_running &
  911. BCM_LED_THREAD_RUNNING_ACTIVELY) {
  912. ad->DriverState = FW_DOWNLOAD_DONE;
  913. wake_up(&ad->LEDInfo.notify_led_event);
  914. }
  915. if (!timeout)
  916. status = -ENODEV;
  917. up(&ad->fw_download_sema);
  918. up(&ad->NVMRdmWrmLock);
  919. return status;
  920. }
  921. static int bcm_char_ioctl_chip_reset(struct bcm_mini_adapter *ad)
  922. {
  923. INT status;
  924. INT nvm_access;
  925. nvm_access = down_trylock(&ad->NVMRdmWrmLock);
  926. if (nvm_access) {
  927. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  928. " IOCTL_BCM_CHIP_RESET not allowed as EEPROM Read/Write is in progress\n");
  929. return -EACCES;
  930. }
  931. down(&ad->RxAppControlQueuelock);
  932. status = reset_card_proc(ad);
  933. flushAllAppQ();
  934. up(&ad->RxAppControlQueuelock);
  935. up(&ad->NVMRdmWrmLock);
  936. ResetCounters(ad);
  937. return status;
  938. }
  939. static int bcm_char_ioctl_qos_threshold(ULONG arg,
  940. struct bcm_mini_adapter *ad)
  941. {
  942. USHORT i;
  943. for (i = 0; i < NO_OF_QUEUES; i++) {
  944. if (get_user(ad->PackInfo[i].uiThreshold,
  945. (unsigned long __user *)arg)) {
  946. return -EFAULT;
  947. }
  948. }
  949. return 0;
  950. }
  951. static int bcm_char_ioctl_switch_transfer_mode(void __user *argp,
  952. struct bcm_mini_adapter *ad)
  953. {
  954. UINT data = 0;
  955. if (copy_from_user(&data, argp, sizeof(UINT)))
  956. return -EFAULT;
  957. if (data) {
  958. /* Allow All Packets */
  959. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  960. "IOCTL_BCM_SWITCH_TRANSFER_MODE: ETH_PACKET_TUNNELING_MODE\n");
  961. ad->TransferMode = ETH_PACKET_TUNNELING_MODE;
  962. } else {
  963. /* Allow IP only Packets */
  964. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  965. "IOCTL_BCM_SWITCH_TRANSFER_MODE: IP_PACKET_ONLY_MODE\n");
  966. ad->TransferMode = IP_PACKET_ONLY_MODE;
  967. }
  968. return STATUS_SUCCESS;
  969. }
  970. static int bcm_char_ioctl_get_driver_version(void __user *argp)
  971. {
  972. struct bcm_ioctl_buffer io_buff;
  973. ulong len;
  974. /* Copy Ioctl Buffer structure */
  975. if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer)))
  976. return -EFAULT;
  977. len = min_t(ulong, io_buff.OutputLength, strlen(DRV_VERSION) + 1);
  978. if (copy_to_user(io_buff.OutputBuffer, DRV_VERSION, len))
  979. return -EFAULT;
  980. return STATUS_SUCCESS;
  981. }
  982. static int bcm_char_ioctl_get_current_status(void __user *argp,
  983. struct bcm_mini_adapter *ad)
  984. {
  985. struct bcm_link_state link_state;
  986. struct bcm_ioctl_buffer io_buff;
  987. /* Copy Ioctl Buffer structure */
  988. if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) {
  989. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  990. "copy_from_user failed..\n");
  991. return -EFAULT;
  992. }
  993. if (io_buff.OutputLength != sizeof(link_state))
  994. return -EINVAL;
  995. memset(&link_state, 0, sizeof(link_state));
  996. link_state.bIdleMode = ad->IdleMode;
  997. link_state.bShutdownMode = ad->bShutStatus;
  998. link_state.ucLinkStatus = ad->LinkStatus;
  999. if (copy_to_user(io_buff.OutputBuffer, &link_state, min_t(size_t,
  1000. sizeof(link_state), io_buff.OutputLength))) {
  1001. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  1002. "Copy_to_user Failed..\n");
  1003. return -EFAULT;
  1004. }
  1005. return STATUS_SUCCESS;
  1006. }
  1007. static int bcm_char_ioctl_set_mac_tracing(void __user *argp,
  1008. struct bcm_mini_adapter *ad)
  1009. {
  1010. struct bcm_ioctl_buffer io_buff;
  1011. UINT tracing_flag;
  1012. /* copy ioctl Buffer structure */
  1013. if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer)))
  1014. return -EFAULT;
  1015. if (copy_from_user(&tracing_flag, io_buff.InputBuffer, sizeof(UINT)))
  1016. return -EFAULT;
  1017. if (tracing_flag)
  1018. ad->pTarangs->MacTracingEnabled = TRUE;
  1019. else
  1020. ad->pTarangs->MacTracingEnabled = false;
  1021. return STATUS_SUCCESS;
  1022. }
  1023. static int bcm_char_ioctl_get_dsx_indication(void __user *argp,
  1024. struct bcm_mini_adapter *ad)
  1025. {
  1026. struct bcm_ioctl_buffer io_buff;
  1027. ULONG sf_id = 0;
  1028. if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer)))
  1029. return -EFAULT;
  1030. if (io_buff.OutputLength < sizeof(struct bcm_add_indication_alt)) {
  1031. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  1032. "Mismatch req: %lx needed is =0x%zx!!!",
  1033. io_buff.OutputLength,
  1034. sizeof(struct bcm_add_indication_alt));
  1035. return -EINVAL;
  1036. }
  1037. if (copy_from_user(&sf_id, io_buff.InputBuffer, sizeof(sf_id)))
  1038. return -EFAULT;
  1039. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  1040. "Get DSX Data SF ID is =%lx\n", sf_id);
  1041. get_dsx_sf_data_to_application(ad, sf_id, io_buff.OutputBuffer);
  1042. return STATUS_SUCCESS;
  1043. }
  1044. static int bcm_char_ioctl_get_host_mibs(void __user *argp,
  1045. struct bcm_mini_adapter *ad,
  1046. struct bcm_tarang_data *tarang)
  1047. {
  1048. struct bcm_ioctl_buffer io_buff;
  1049. INT status = STATUS_FAILURE;
  1050. PVOID temp_buff;
  1051. if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer)))
  1052. return -EFAULT;
  1053. if (io_buff.OutputLength != sizeof(struct bcm_host_stats_mibs)) {
  1054. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  1055. "Length Check failed %lu %zd\n", io_buff.OutputLength,
  1056. sizeof(struct bcm_host_stats_mibs));
  1057. return -EINVAL;
  1058. }
  1059. /* FIXME: HOST_STATS are too big for kmalloc (122048)! */
  1060. temp_buff = kzalloc(sizeof(struct bcm_host_stats_mibs), GFP_KERNEL);
  1061. if (!temp_buff)
  1062. return STATUS_FAILURE;
  1063. status = ProcessGetHostMibs(ad, temp_buff);
  1064. GetDroppedAppCntrlPktMibs(temp_buff, tarang);
  1065. if (status != STATUS_FAILURE) {
  1066. if (copy_to_user(io_buff.OutputBuffer, temp_buff,
  1067. sizeof(struct bcm_host_stats_mibs))) {
  1068. kfree(temp_buff);
  1069. return -EFAULT;
  1070. }
  1071. }
  1072. kfree(temp_buff);
  1073. return status;
  1074. }
  1075. static int bcm_char_ioctl_bulk_wrm(void __user *argp,
  1076. struct bcm_mini_adapter *ad, UINT cmd)
  1077. {
  1078. struct bcm_bulk_wrm_buffer *bulk_buff;
  1079. struct bcm_ioctl_buffer io_buff;
  1080. UINT tmp = 0;
  1081. INT status = STATUS_FAILURE;
  1082. PCHAR buff = NULL;
  1083. if ((ad->IdleMode == TRUE) ||
  1084. (ad->bShutStatus == TRUE) ||
  1085. (ad->bPreparingForLowPowerMode == TRUE)) {
  1086. BCM_DEBUG_PRINT (ad, DBG_TYPE_PRINTK, 0, 0,
  1087. "Device in Idle/Shutdown Mode, Blocking Wrms\n");
  1088. return -EACCES;
  1089. }
  1090. /* Copy Ioctl Buffer structure */
  1091. if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer)))
  1092. return -EFAULT;
  1093. if (io_buff.InputLength < sizeof(ULONG) * 2)
  1094. return -EINVAL;
  1095. buff = memdup_user(io_buff.InputBuffer,
  1096. io_buff.InputLength);
  1097. if (IS_ERR(buff))
  1098. return PTR_ERR(buff);
  1099. bulk_buff = (struct bcm_bulk_wrm_buffer *)buff;
  1100. if (((ULONG)bulk_buff->Register & 0x0F000000) != 0x0F000000 ||
  1101. ((ULONG)bulk_buff->Register & 0x3)) {
  1102. BCM_DEBUG_PRINT (ad, DBG_TYPE_PRINTK, 0, 0,
  1103. "WRM Done On invalid Address : %x Access Denied.\n",
  1104. (int)bulk_buff->Register);
  1105. kfree(buff);
  1106. return -EINVAL;
  1107. }
  1108. tmp = bulk_buff->Register & EEPROM_REJECT_MASK;
  1109. if (!((ad->pstargetparams->m_u32Customize)&VSG_MODE) &&
  1110. ((tmp == EEPROM_REJECT_REG_1) ||
  1111. (tmp == EEPROM_REJECT_REG_2) ||
  1112. (tmp == EEPROM_REJECT_REG_3) ||
  1113. (tmp == EEPROM_REJECT_REG_4)) &&
  1114. (cmd == IOCTL_BCM_REGISTER_WRITE)) {
  1115. kfree(buff);
  1116. BCM_DEBUG_PRINT (ad, DBG_TYPE_PRINTK, 0, 0,
  1117. "EEPROM Access Denied, not in VSG Mode\n");
  1118. return -EFAULT;
  1119. }
  1120. if (bulk_buff->SwapEndian == false)
  1121. status = wrmWithLock(ad, (UINT)bulk_buff->Register,
  1122. (PCHAR)bulk_buff->Values,
  1123. io_buff.InputLength - 2*sizeof(ULONG));
  1124. else
  1125. status = wrmaltWithLock(ad, (UINT)bulk_buff->Register,
  1126. (PUINT)bulk_buff->Values,
  1127. io_buff.InputLength - 2*sizeof(ULONG));
  1128. if (status != STATUS_SUCCESS)
  1129. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, "WRM Failed\n");
  1130. kfree(buff);
  1131. return status;
  1132. }
  1133. static int bcm_char_ioctl_get_nvm_size(void __user *argp,
  1134. struct bcm_mini_adapter *ad)
  1135. {
  1136. struct bcm_ioctl_buffer io_buff;
  1137. if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer)))
  1138. return -EFAULT;
  1139. if (ad->eNVMType == NVM_EEPROM || ad->eNVMType == NVM_FLASH) {
  1140. if (copy_to_user(io_buff.OutputBuffer, &ad->uiNVMDSDSize,
  1141. sizeof(UINT)))
  1142. return -EFAULT;
  1143. }
  1144. return STATUS_SUCCESS;
  1145. }
  1146. static int bcm_char_ioctl_cal_init(void __user *argp,
  1147. struct bcm_mini_adapter *ad)
  1148. {
  1149. struct bcm_ioctl_buffer io_buff;
  1150. UINT sector_size = 0;
  1151. INT status = STATUS_FAILURE;
  1152. if (ad->eNVMType == NVM_FLASH) {
  1153. if (copy_from_user(&io_buff, argp,
  1154. sizeof(struct bcm_ioctl_buffer)))
  1155. return -EFAULT;
  1156. if (copy_from_user(&sector_size, io_buff.InputBuffer,
  1157. sizeof(UINT)))
  1158. return -EFAULT;
  1159. if ((sector_size < MIN_SECTOR_SIZE) ||
  1160. (sector_size > MAX_SECTOR_SIZE)) {
  1161. if (copy_to_user(io_buff.OutputBuffer,
  1162. &ad->uiSectorSize, sizeof(UINT)))
  1163. return -EFAULT;
  1164. } else {
  1165. if (IsFlash2x(ad)) {
  1166. if (copy_to_user(io_buff.OutputBuffer,
  1167. &ad->uiSectorSize, sizeof(UINT)))
  1168. return -EFAULT;
  1169. } else {
  1170. if ((TRUE == ad->bShutStatus) ||
  1171. (TRUE == ad->IdleMode)) {
  1172. BCM_DEBUG_PRINT(ad,
  1173. DBG_TYPE_PRINTK, 0, 0,
  1174. "Device is in Idle/Shutdown Mode\n");
  1175. return -EACCES;
  1176. }
  1177. ad->uiSectorSize = sector_size;
  1178. BcmUpdateSectorSize(ad,
  1179. ad->uiSectorSize);
  1180. }
  1181. }
  1182. status = STATUS_SUCCESS;
  1183. } else {
  1184. status = STATUS_FAILURE;
  1185. }
  1186. return status;
  1187. }
  1188. static int bcm_char_ioctl_set_debug(void __user *argp,
  1189. struct bcm_mini_adapter *ad)
  1190. {
  1191. #ifdef DEBUG
  1192. struct bcm_ioctl_buffer io_buff;
  1193. struct bcm_user_debug_state user_debug_state;
  1194. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  1195. "In SET_DEBUG ioctl\n");
  1196. if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer)))
  1197. return -EFAULT;
  1198. if (copy_from_user(&user_debug_state, io_buff.InputBuffer,
  1199. sizeof(struct bcm_user_debug_state)))
  1200. return -EFAULT;
  1201. BCM_DEBUG_PRINT (ad, DBG_TYPE_PRINTK, 0, 0,
  1202. "IOCTL_BCM_SET_DEBUG: OnOff=%d Type = 0x%x ",
  1203. user_debug_state.OnOff, user_debug_state.Type);
  1204. /* user_debug_state.Subtype <<= 1; */
  1205. user_debug_state.Subtype = 1 << user_debug_state.Subtype;
  1206. BCM_DEBUG_PRINT (ad, DBG_TYPE_PRINTK, 0, 0,
  1207. "actual Subtype=0x%x\n", user_debug_state.Subtype);
  1208. /* Update new 'DebugState' in the ad */
  1209. ad->stDebugState.type |= user_debug_state.Type;
  1210. /* Subtype: A bitmap of 32 bits for Subtype per Type.
  1211. * Valid indexes in 'subtype' array: 1,2,4,8
  1212. * corresponding to valid Type values. Hence we can use the 'Type' field
  1213. * as the index value, ignoring the array entries 0,3,5,6,7 !
  1214. */
  1215. if (user_debug_state.OnOff)
  1216. ad->stDebugState.subtype[user_debug_state.Type] |=
  1217. user_debug_state.Subtype;
  1218. else
  1219. ad->stDebugState.subtype[user_debug_state.Type] &=
  1220. ~user_debug_state.Subtype;
  1221. BCM_SHOW_DEBUG_BITMAP(ad);
  1222. #endif
  1223. return STATUS_SUCCESS;
  1224. }
  1225. static int bcm_char_ioctl_nvm_rw(void __user *argp,
  1226. struct bcm_mini_adapter *ad, UINT cmd)
  1227. {
  1228. struct bcm_nvm_readwrite nvm_rw;
  1229. struct timeval tv0, tv1;
  1230. struct bcm_ioctl_buffer io_buff;
  1231. PUCHAR read_data = NULL;
  1232. INT status = STATUS_FAILURE;
  1233. memset(&tv0, 0, sizeof(struct timeval));
  1234. memset(&tv1, 0, sizeof(struct timeval));
  1235. if ((ad->eNVMType == NVM_FLASH) &&
  1236. (ad->uiFlashLayoutMajorVersion == 0)) {
  1237. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  1238. "The Flash Control Section is Corrupted. Hence Rejection on NVM Read/Write\n");
  1239. return -EFAULT;
  1240. }
  1241. if (IsFlash2x(ad)) {
  1242. if ((ad->eActiveDSD != DSD0) &&
  1243. (ad->eActiveDSD != DSD1) &&
  1244. (ad->eActiveDSD != DSD2)) {
  1245. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  1246. "No DSD is active..hence NVM Command is blocked");
  1247. return STATUS_FAILURE;
  1248. }
  1249. }
  1250. /* Copy Ioctl Buffer structure */
  1251. if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer)))
  1252. return -EFAULT;
  1253. if (copy_from_user(&nvm_rw,
  1254. (IOCTL_BCM_NVM_READ == cmd) ?
  1255. io_buff.OutputBuffer : io_buff.InputBuffer,
  1256. sizeof(struct bcm_nvm_readwrite)))
  1257. return -EFAULT;
  1258. /*
  1259. * Deny the access if the offset crosses the cal area limit.
  1260. */
  1261. if (nvm_rw.uiNumBytes > ad->uiNVMDSDSize)
  1262. return STATUS_FAILURE;
  1263. if (nvm_rw.uiOffset >
  1264. ad->uiNVMDSDSize - nvm_rw.uiNumBytes)
  1265. return STATUS_FAILURE;
  1266. read_data = memdup_user(nvm_rw.pBuffer,
  1267. nvm_rw.uiNumBytes);
  1268. if (IS_ERR(read_data))
  1269. return PTR_ERR(read_data);
  1270. do_gettimeofday(&tv0);
  1271. if (IOCTL_BCM_NVM_READ == cmd) {
  1272. int ret = bcm_handle_nvm_read_cmd(ad, read_data,
  1273. &nvm_rw);
  1274. if (ret != STATUS_SUCCESS)
  1275. return ret;
  1276. } else {
  1277. down(&ad->NVMRdmWrmLock);
  1278. if ((ad->IdleMode == TRUE) ||
  1279. (ad->bShutStatus == TRUE) ||
  1280. (ad->bPreparingForLowPowerMode == TRUE)) {
  1281. BCM_DEBUG_PRINT(ad,
  1282. DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  1283. "Device is in Idle/Shutdown Mode\n");
  1284. up(&ad->NVMRdmWrmLock);
  1285. kfree(read_data);
  1286. return -EACCES;
  1287. }
  1288. ad->bHeaderChangeAllowed = TRUE;
  1289. if (IsFlash2x(ad)) {
  1290. int ret = handle_flash2x_adapter(ad,
  1291. read_data,
  1292. &nvm_rw);
  1293. if (ret != STATUS_SUCCESS)
  1294. return ret;
  1295. }
  1296. status = BeceemNVMWrite(ad, (PUINT)read_data,
  1297. nvm_rw.uiOffset, nvm_rw.uiNumBytes,
  1298. nvm_rw.bVerify);
  1299. if (IsFlash2x(ad))
  1300. BcmFlash2xWriteSig(ad, ad->eActiveDSD);
  1301. ad->bHeaderChangeAllowed = false;
  1302. up(&ad->NVMRdmWrmLock);
  1303. if (status != STATUS_SUCCESS) {
  1304. kfree(read_data);
  1305. return status;
  1306. }
  1307. }
  1308. do_gettimeofday(&tv1);
  1309. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  1310. " timetaken by Write/read :%ld msec\n",
  1311. (tv1.tv_sec - tv0.tv_sec)*1000 +
  1312. (tv1.tv_usec - tv0.tv_usec)/1000);
  1313. kfree(read_data);
  1314. return STATUS_SUCCESS;
  1315. }
  1316. static int bcm_char_ioctl_flash2x_section_read(void __user *argp,
  1317. struct bcm_mini_adapter *ad)
  1318. {
  1319. struct bcm_flash2x_readwrite flash_2x_read = {0};
  1320. struct bcm_ioctl_buffer io_buff;
  1321. PUCHAR read_buff = NULL;
  1322. UINT nob = 0;
  1323. UINT buff_size = 0;
  1324. UINT read_bytes = 0;
  1325. UINT read_offset = 0;
  1326. INT status = STATUS_FAILURE;
  1327. void __user *OutPutBuff;
  1328. if (IsFlash2x(ad) != TRUE) {
  1329. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  1330. "Flash Does not have 2.x map");
  1331. return -EINVAL;
  1332. }
  1333. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG,
  1334. DBG_LVL_ALL, "IOCTL_BCM_FLASH2X_SECTION_READ Called");
  1335. if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer)))
  1336. return -EFAULT;
  1337. /* Reading FLASH 2.x READ structure */
  1338. if (copy_from_user(&flash_2x_read, io_buff.InputBuffer,
  1339. sizeof(struct bcm_flash2x_readwrite)))
  1340. return -EFAULT;
  1341. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  1342. "\nflash_2x_read.Section :%x",
  1343. flash_2x_read.Section);
  1344. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  1345. "\nflash_2x_read.offset :%x",
  1346. flash_2x_read.offset);
  1347. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  1348. "\nflash_2x_read.numOfBytes :%x",
  1349. flash_2x_read.numOfBytes);
  1350. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  1351. "\nflash_2x_read.bVerify :%x\n",
  1352. flash_2x_read.bVerify);
  1353. /* This was internal to driver for raw read.
  1354. * now it has ben exposed to user space app.
  1355. */
  1356. if (validateFlash2xReadWrite(ad, &flash_2x_read) == false)
  1357. return STATUS_FAILURE;
  1358. nob = flash_2x_read.numOfBytes;
  1359. if (nob > ad->uiSectorSize)
  1360. buff_size = ad->uiSectorSize;
  1361. else
  1362. buff_size = nob;
  1363. read_offset = flash_2x_read.offset;
  1364. OutPutBuff = io_buff.OutputBuffer;
  1365. read_buff = kzalloc(buff_size , GFP_KERNEL);
  1366. if (read_buff == NULL) {
  1367. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  1368. "Memory allocation failed for Flash 2.x Read Structure");
  1369. return -ENOMEM;
  1370. }
  1371. down(&ad->NVMRdmWrmLock);
  1372. if ((ad->IdleMode == TRUE) ||
  1373. (ad->bShutStatus == TRUE) ||
  1374. (ad->bPreparingForLowPowerMode == TRUE)) {
  1375. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG,
  1376. DBG_LVL_ALL,
  1377. "Device is in Idle/Shutdown Mode\n");
  1378. up(&ad->NVMRdmWrmLock);
  1379. kfree(read_buff);
  1380. return -EACCES;
  1381. }
  1382. while (nob) {
  1383. if (nob > ad->uiSectorSize)
  1384. read_bytes = ad->uiSectorSize;
  1385. else
  1386. read_bytes = nob;
  1387. /* Reading the data from Flash 2.x */
  1388. status = BcmFlash2xBulkRead(ad, (PUINT)read_buff,
  1389. flash_2x_read.Section, read_offset, read_bytes);
  1390. if (status) {
  1391. BCM_DEBUG_PRINT(ad,
  1392. DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  1393. "Flash 2x read err with status :%d",
  1394. status);
  1395. break;
  1396. }
  1397. BCM_DEBUG_PRINT_BUFFER(ad, DBG_TYPE_OTHERS, OSAL_DBG,
  1398. DBG_LVL_ALL, read_buff, read_bytes);
  1399. status = copy_to_user(OutPutBuff, read_buff, read_bytes);
  1400. if (status) {
  1401. BCM_DEBUG_PRINT(ad,
  1402. DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  1403. "Copy to use failed with status :%d", status);
  1404. up(&ad->NVMRdmWrmLock);
  1405. kfree(read_buff);
  1406. return -EFAULT;
  1407. }
  1408. nob = nob - read_bytes;
  1409. if (nob) {
  1410. read_offset = read_offset + read_bytes;
  1411. OutPutBuff = OutPutBuff + read_bytes;
  1412. }
  1413. }
  1414. up(&ad->NVMRdmWrmLock);
  1415. kfree(read_buff);
  1416. return status;
  1417. }
  1418. static int bcm_char_ioctl_flash2x_section_write(void __user *argp,
  1419. struct bcm_mini_adapter *ad)
  1420. {
  1421. struct bcm_flash2x_readwrite sFlash2xWrite = {0};
  1422. struct bcm_ioctl_buffer io_buff;
  1423. PUCHAR write_buff;
  1424. void __user *input_addr;
  1425. UINT nob = 0;
  1426. UINT buff_size = 0;
  1427. UINT write_off = 0;
  1428. UINT write_bytes = 0;
  1429. INT status = STATUS_FAILURE;
  1430. if (IsFlash2x(ad) != TRUE) {
  1431. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  1432. "Flash Does not have 2.x map");
  1433. return -EINVAL;
  1434. }
  1435. /* First make this False so that we can enable the Sector
  1436. * Permission Check in BeceemFlashBulkWrite
  1437. */
  1438. ad->bAllDSDWriteAllow = false;
  1439. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  1440. "IOCTL_BCM_FLASH2X_SECTION_WRITE Called");
  1441. if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer)))
  1442. return -EFAULT;
  1443. /* Reading FLASH 2.x READ structure */
  1444. if (copy_from_user(&sFlash2xWrite, io_buff.InputBuffer,
  1445. sizeof(struct bcm_flash2x_readwrite)))
  1446. return -EFAULT;
  1447. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  1448. "\nsFlash2xWrite.Section :%x", sFlash2xWrite.Section);
  1449. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  1450. "\nsFlash2xWrite.offset :%d", sFlash2xWrite.offset);
  1451. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  1452. "\nsFlash2xWrite.numOfBytes :%x", sFlash2xWrite.numOfBytes);
  1453. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  1454. "\nsFlash2xWrite.bVerify :%x\n", sFlash2xWrite.bVerify);
  1455. if ((sFlash2xWrite.Section != VSA0) && (sFlash2xWrite.Section != VSA1)
  1456. && (sFlash2xWrite.Section != VSA2)) {
  1457. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  1458. "Only VSA write is allowed");
  1459. return -EINVAL;
  1460. }
  1461. if (validateFlash2xReadWrite(ad, &sFlash2xWrite) == false)
  1462. return STATUS_FAILURE;
  1463. input_addr = sFlash2xWrite.pDataBuff;
  1464. write_off = sFlash2xWrite.offset;
  1465. nob = sFlash2xWrite.numOfBytes;
  1466. if (nob > ad->uiSectorSize)
  1467. buff_size = ad->uiSectorSize;
  1468. else
  1469. buff_size = nob;
  1470. write_buff = kmalloc(buff_size, GFP_KERNEL);
  1471. if (write_buff == NULL)
  1472. return -ENOMEM;
  1473. /* extracting the remainder of the given offset. */
  1474. write_bytes = ad->uiSectorSize;
  1475. if (write_off % ad->uiSectorSize) {
  1476. write_bytes = ad->uiSectorSize -
  1477. (write_off % ad->uiSectorSize);
  1478. }
  1479. if (nob < write_bytes)
  1480. write_bytes = nob;
  1481. down(&ad->NVMRdmWrmLock);
  1482. if ((ad->IdleMode == TRUE) ||
  1483. (ad->bShutStatus == TRUE) ||
  1484. (ad->bPreparingForLowPowerMode == TRUE)) {
  1485. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  1486. "Device is in Idle/Shutdown Mode\n");
  1487. up(&ad->NVMRdmWrmLock);
  1488. kfree(write_buff);
  1489. return -EACCES;
  1490. }
  1491. BcmFlash2xCorruptSig(ad, sFlash2xWrite.Section);
  1492. do {
  1493. status = copy_from_user(write_buff, input_addr, write_bytes);
  1494. if (status) {
  1495. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  1496. "Copy to user failed with status :%d", status);
  1497. up(&ad->NVMRdmWrmLock);
  1498. kfree(write_buff);
  1499. return -EFAULT;
  1500. }
  1501. BCM_DEBUG_PRINT_BUFFER(ad, DBG_TYPE_OTHERS,
  1502. OSAL_DBG, DBG_LVL_ALL, write_buff, write_bytes);
  1503. /* Writing the data from Flash 2.x */
  1504. status = BcmFlash2xBulkWrite(ad, (PUINT)write_buff,
  1505. sFlash2xWrite.Section,
  1506. write_off,
  1507. write_bytes,
  1508. sFlash2xWrite.bVerify);
  1509. if (status) {
  1510. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  1511. "Flash 2x read err with status :%d", status);
  1512. break;
  1513. }
  1514. nob = nob - write_bytes;
  1515. if (nob) {
  1516. write_off = write_off + write_bytes;
  1517. input_addr = input_addr + write_bytes;
  1518. if (nob > ad->uiSectorSize)
  1519. write_bytes = ad->uiSectorSize;
  1520. else
  1521. write_bytes = nob;
  1522. }
  1523. } while (nob > 0);
  1524. BcmFlash2xWriteSig(ad, sFlash2xWrite.Section);
  1525. up(&ad->NVMRdmWrmLock);
  1526. kfree(write_buff);
  1527. return status;
  1528. }
  1529. static int bcm_char_ioctl_flash2x_section_bitmap(void __user *argp,
  1530. struct bcm_mini_adapter *ad)
  1531. {
  1532. struct bcm_flash2x_bitmap *flash_2x_bit_map;
  1533. struct bcm_ioctl_buffer io_buff;
  1534. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  1535. "IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP Called");
  1536. if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer)))
  1537. return -EFAULT;
  1538. if (io_buff.OutputLength != sizeof(struct bcm_flash2x_bitmap))
  1539. return -EINVAL;
  1540. flash_2x_bit_map = kzalloc(sizeof(struct bcm_flash2x_bitmap),
  1541. GFP_KERNEL);
  1542. if (flash_2x_bit_map == NULL) {
  1543. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  1544. "Memory is not available");
  1545. return -ENOMEM;
  1546. }
  1547. /* Reading the Flash Sectio Bit map */
  1548. down(&ad->NVMRdmWrmLock);
  1549. if ((ad->IdleMode == TRUE) ||
  1550. (ad->bShutStatus == TRUE) ||
  1551. (ad->bPreparingForLowPowerMode == TRUE)) {
  1552. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  1553. "Device is in Idle/Shutdown Mode\n");
  1554. up(&ad->NVMRdmWrmLock);
  1555. kfree(flash_2x_bit_map);
  1556. return -EACCES;
  1557. }
  1558. BcmGetFlash2xSectionalBitMap(ad, flash_2x_bit_map);
  1559. up(&ad->NVMRdmWrmLock);
  1560. if (copy_to_user(io_buff.OutputBuffer, flash_2x_bit_map,
  1561. sizeof(struct bcm_flash2x_bitmap))) {
  1562. kfree(flash_2x_bit_map);
  1563. return -EFAULT;
  1564. }
  1565. kfree(flash_2x_bit_map);
  1566. return STATUS_FAILURE;
  1567. }
  1568. static int bcm_char_ioctl_set_active_section(void __user *argp,
  1569. struct bcm_mini_adapter *ad)
  1570. {
  1571. enum bcm_flash2x_section_val flash_2x_section_val = 0;
  1572. INT status = STATUS_FAILURE;
  1573. struct bcm_ioctl_buffer io_buff;
  1574. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  1575. "IOCTL_BCM_SET_ACTIVE_SECTION Called");
  1576. if (IsFlash2x(ad) != TRUE) {
  1577. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  1578. "Flash Does not have 2.x map");
  1579. return -EINVAL;
  1580. }
  1581. status = copy_from_user(&io_buff, argp,
  1582. sizeof(struct bcm_ioctl_buffer));
  1583. if (status) {
  1584. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  1585. "Copy of IOCTL BUFFER failed");
  1586. return -EFAULT;
  1587. }
  1588. status = copy_from_user(&flash_2x_section_val,
  1589. io_buff.InputBuffer, sizeof(INT));
  1590. if (status) {
  1591. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  1592. "Copy of flash section val failed");
  1593. return -EFAULT;
  1594. }
  1595. down(&ad->NVMRdmWrmLock);
  1596. if ((ad->IdleMode == TRUE) ||
  1597. (ad->bShutStatus == TRUE) ||
  1598. (ad->bPreparingForLowPowerMode == TRUE)) {
  1599. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  1600. "Device is in Idle/Shutdown Mode\n");
  1601. up(&ad->NVMRdmWrmLock);
  1602. return -EACCES;
  1603. }
  1604. status = BcmSetActiveSection(ad, flash_2x_section_val);
  1605. if (status)
  1606. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  1607. "Failed to make it's priority Highest. status %d",
  1608. status);
  1609. up(&ad->NVMRdmWrmLock);
  1610. return status;
  1611. }
  1612. static int bcm_char_ioctl_copy_section(void __user *argp,
  1613. struct bcm_mini_adapter *ad)
  1614. {
  1615. struct bcm_flash2x_copy_section copy_sect_strut = {0};
  1616. struct bcm_ioctl_buffer io_buff;
  1617. INT status = STATUS_SUCCESS;
  1618. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  1619. "IOCTL_BCM_COPY_SECTION Called");
  1620. ad->bAllDSDWriteAllow = false;
  1621. if (IsFlash2x(ad) != TRUE) {
  1622. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  1623. "Flash Does not have 2.x map");
  1624. return -EINVAL;
  1625. }
  1626. status = copy_from_user(&io_buff, argp,
  1627. sizeof(struct bcm_ioctl_buffer));
  1628. if (status) {
  1629. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  1630. "Copy of IOCTL BUFFER failed status :%d",
  1631. status);
  1632. return -EFAULT;
  1633. }
  1634. status = copy_from_user(&copy_sect_strut, io_buff.InputBuffer,
  1635. sizeof(struct bcm_flash2x_copy_section));
  1636. if (status) {
  1637. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  1638. "Copy of Copy_Section_Struct failed with status :%d",
  1639. status);
  1640. return -EFAULT;
  1641. }
  1642. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  1643. "Source SEction :%x", copy_sect_strut.SrcSection);
  1644. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  1645. "Destination SEction :%x", copy_sect_strut.DstSection);
  1646. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  1647. "offset :%x", copy_sect_strut.offset);
  1648. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  1649. "nob :%x", copy_sect_strut.numOfBytes);
  1650. if (IsSectionExistInFlash(ad, copy_sect_strut.SrcSection) == false) {
  1651. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  1652. "Source Section<%x> does not exist in Flash ",
  1653. copy_sect_strut.SrcSection);
  1654. return -EINVAL;
  1655. }
  1656. if (IsSectionExistInFlash(ad, copy_sect_strut.DstSection) == false) {
  1657. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  1658. "Destinatio Section<%x> does not exist in Flash ",
  1659. copy_sect_strut.DstSection);
  1660. return -EINVAL;
  1661. }
  1662. if (copy_sect_strut.SrcSection == copy_sect_strut.DstSection) {
  1663. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  1664. "Source and Destination section should be different");
  1665. return -EINVAL;
  1666. }
  1667. down(&ad->NVMRdmWrmLock);
  1668. if ((ad->IdleMode == TRUE) ||
  1669. (ad->bShutStatus == TRUE) ||
  1670. (ad->bPreparingForLowPowerMode == TRUE)) {
  1671. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  1672. "Device is in Idle/Shutdown Mode\n");
  1673. up(&ad->NVMRdmWrmLock);
  1674. return -EACCES;
  1675. }
  1676. if (copy_sect_strut.SrcSection == ISO_IMAGE1 ||
  1677. copy_sect_strut.SrcSection == ISO_IMAGE2) {
  1678. if (IsNonCDLessDevice(ad)) {
  1679. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  1680. "Device is Non-CDLess hence won't have ISO !!");
  1681. status = -EINVAL;
  1682. } else if (copy_sect_strut.numOfBytes == 0) {
  1683. status = BcmCopyISO(ad, copy_sect_strut);
  1684. } else {
  1685. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  1686. "Partial Copy of ISO section is not Allowed..");
  1687. status = STATUS_FAILURE;
  1688. }
  1689. up(&ad->NVMRdmWrmLock);
  1690. return status;
  1691. }
  1692. status = BcmCopySection(ad, copy_sect_strut.SrcSection,
  1693. copy_sect_strut.DstSection,
  1694. copy_sect_strut.offset,
  1695. copy_sect_strut.numOfBytes);
  1696. up(&ad->NVMRdmWrmLock);
  1697. return status;
  1698. }
  1699. static int bcm_char_ioctl_get_flash_cs_info(void __user *argp,
  1700. struct bcm_mini_adapter *ad)
  1701. {
  1702. struct bcm_ioctl_buffer io_buff;
  1703. INT status = STATUS_SUCCESS;
  1704. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  1705. " IOCTL_BCM_GET_FLASH_CS_INFO Called");
  1706. status = copy_from_user(&io_buff, argp,
  1707. sizeof(struct bcm_ioctl_buffer));
  1708. if (status) {
  1709. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  1710. "Copy of IOCTL BUFFER failed");
  1711. return -EFAULT;
  1712. }
  1713. if (ad->eNVMType != NVM_FLASH) {
  1714. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  1715. "Connected device does not have flash");
  1716. return -EINVAL;
  1717. }
  1718. if (IsFlash2x(ad) == TRUE) {
  1719. if (io_buff.OutputLength < sizeof(struct bcm_flash2x_cs_info))
  1720. return -EINVAL;
  1721. if (copy_to_user(io_buff.OutputBuffer,
  1722. ad->psFlash2xCSInfo,
  1723. sizeof(struct bcm_flash2x_cs_info)))
  1724. return -EFAULT;
  1725. } else {
  1726. if (io_buff.OutputLength < sizeof(struct bcm_flash_cs_info))
  1727. return -EINVAL;
  1728. if (copy_to_user(io_buff.OutputBuffer, ad->psFlashCSInfo,
  1729. sizeof(struct bcm_flash_cs_info)))
  1730. return -EFAULT;
  1731. }
  1732. return status;
  1733. }
  1734. static int bcm_char_ioctl_select_dsd(void __user *argp,
  1735. struct bcm_mini_adapter *ad)
  1736. {
  1737. struct bcm_ioctl_buffer io_buff;
  1738. INT status = STATUS_FAILURE;
  1739. UINT sect_offset = 0;
  1740. enum bcm_flash2x_section_val flash_2x_section_val;
  1741. flash_2x_section_val = NO_SECTION_VAL;
  1742. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  1743. "IOCTL_BCM_SELECT_DSD Called");
  1744. if (IsFlash2x(ad) != TRUE) {
  1745. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  1746. "Flash Does not have 2.x map");
  1747. return -EINVAL;
  1748. }
  1749. status = copy_from_user(&io_buff, argp,
  1750. sizeof(struct bcm_ioctl_buffer));
  1751. if (status) {
  1752. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  1753. "Copy of IOCTL BUFFER failed");
  1754. return -EFAULT;
  1755. }
  1756. status = copy_from_user(&flash_2x_section_val, io_buff.InputBuffer,
  1757. sizeof(INT));
  1758. if (status) {
  1759. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  1760. "Copy of flash section val failed");
  1761. return -EFAULT;
  1762. }
  1763. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  1764. "Read Section :%d", flash_2x_section_val);
  1765. if ((flash_2x_section_val != DSD0) &&
  1766. (flash_2x_section_val != DSD1) &&
  1767. (flash_2x_section_val != DSD2)) {
  1768. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  1769. "Passed section<%x> is not DSD section",
  1770. flash_2x_section_val);
  1771. return STATUS_FAILURE;
  1772. }
  1773. sect_offset = BcmGetSectionValStartOffset(ad, flash_2x_section_val);
  1774. if (sect_offset == INVALID_OFFSET) {
  1775. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  1776. "Provided Section val <%d> does not exist in Flash 2.x",
  1777. flash_2x_section_val);
  1778. return -EINVAL;
  1779. }
  1780. ad->bAllDSDWriteAllow = TRUE;
  1781. ad->ulFlashCalStart = sect_offset;
  1782. ad->eActiveDSD = flash_2x_section_val;
  1783. return STATUS_SUCCESS;
  1784. }
  1785. static int bcm_char_ioctl_nvm_raw_read(void __user *argp,
  1786. struct bcm_mini_adapter *ad)
  1787. {
  1788. struct bcm_nvm_readwrite nvm_read;
  1789. struct bcm_ioctl_buffer io_buff;
  1790. unsigned int nob;
  1791. INT buff_size;
  1792. INT read_offset = 0;
  1793. UINT read_bytes = 0;
  1794. PUCHAR read_buff;
  1795. void __user *OutPutBuff;
  1796. INT status = STATUS_FAILURE;
  1797. if (ad->eNVMType != NVM_FLASH) {
  1798. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  1799. "NVM TYPE is not Flash");
  1800. return -EINVAL;
  1801. }
  1802. /* Copy Ioctl Buffer structure */
  1803. if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) {
  1804. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  1805. "copy_from_user 1 failed\n");
  1806. return -EFAULT;
  1807. }
  1808. if (copy_from_user(&nvm_read, io_buff.OutputBuffer,
  1809. sizeof(struct bcm_nvm_readwrite)))
  1810. return -EFAULT;
  1811. nob = nvm_read.uiNumBytes;
  1812. /* In Raw-Read max Buff size : 64MB */
  1813. if (nob > DEFAULT_BUFF_SIZE)
  1814. buff_size = DEFAULT_BUFF_SIZE;
  1815. else
  1816. buff_size = nob;
  1817. read_offset = nvm_read.uiOffset;
  1818. OutPutBuff = nvm_read.pBuffer;
  1819. read_buff = kzalloc(buff_size , GFP_KERNEL);
  1820. if (read_buff == NULL) {
  1821. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  1822. "Memory allocation failed for Flash 2.x Read Structure");
  1823. return -ENOMEM;
  1824. }
  1825. down(&ad->NVMRdmWrmLock);
  1826. if ((ad->IdleMode == TRUE) ||
  1827. (ad->bShutStatus == TRUE) ||
  1828. (ad->bPreparingForLowPowerMode == TRUE)) {
  1829. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  1830. "Device is in Idle/Shutdown Mode\n");
  1831. kfree(read_buff);
  1832. up(&ad->NVMRdmWrmLock);
  1833. return -EACCES;
  1834. }
  1835. ad->bFlashRawRead = TRUE;
  1836. while (nob) {
  1837. if (nob > DEFAULT_BUFF_SIZE)
  1838. read_bytes = DEFAULT_BUFF_SIZE;
  1839. else
  1840. read_bytes = nob;
  1841. /* Reading the data from Flash 2.x */
  1842. status = BeceemNVMRead(ad, (PUINT)read_buff,
  1843. read_offset, read_bytes);
  1844. if (status) {
  1845. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  1846. "Flash 2x read err with status :%d",
  1847. status);
  1848. break;
  1849. }
  1850. BCM_DEBUG_PRINT_BUFFER(ad, DBG_TYPE_OTHERS, OSAL_DBG,
  1851. DBG_LVL_ALL, read_buff, read_bytes);
  1852. status = copy_to_user(OutPutBuff, read_buff, read_bytes);
  1853. if (status) {
  1854. BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0,
  1855. "Copy to use failed with status :%d",
  1856. status);
  1857. up(&ad->NVMRdmWrmLock);
  1858. kfree(read_buff);
  1859. return -EFAULT;
  1860. }
  1861. nob = nob - read_bytes;
  1862. if (nob) {
  1863. read_offset = read_offset + read_bytes;
  1864. OutPutBuff = OutPutBuff + read_bytes;
  1865. }
  1866. }
  1867. ad->bFlashRawRead = false;
  1868. up(&ad->NVMRdmWrmLock);
  1869. kfree(read_buff);
  1870. return status;
  1871. }
  1872. static int bcm_char_ioctl_cntrlmsg_mask(void __user *argp,
  1873. struct bcm_mini_adapter *ad,
  1874. struct bcm_tarang_data *tarang)
  1875. {
  1876. struct bcm_ioctl_buffer io_buff;
  1877. INT status = STATUS_FAILURE;
  1878. ULONG rx_cntrl_msg_bit_mask = 0;
  1879. /* Copy Ioctl Buffer structure */
  1880. status = copy_from_user(&io_buff, argp,
  1881. sizeof(struct bcm_ioctl_buffer));
  1882. if (status) {
  1883. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  1884. "copy of Ioctl buffer is failed from user space");
  1885. return -EFAULT;
  1886. }
  1887. if (io_buff.InputLength != sizeof(unsigned long))
  1888. return -EINVAL;
  1889. status = copy_from_user(&rx_cntrl_msg_bit_mask, io_buff.InputBuffer,
  1890. io_buff.InputLength);
  1891. if (status) {
  1892. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  1893. "copy of control bit mask failed from user space");
  1894. return -EFAULT;
  1895. }
  1896. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  1897. "\n Got user defined cntrl msg bit mask :%lx",
  1898. rx_cntrl_msg_bit_mask);
  1899. tarang->RxCntrlMsgBitMask = rx_cntrl_msg_bit_mask;
  1900. return status;
  1901. }
  1902. static int bcm_char_ioctl_get_device_driver_info(void __user *argp,
  1903. struct bcm_mini_adapter *ad)
  1904. {
  1905. struct bcm_driver_info dev_info;
  1906. struct bcm_ioctl_buffer io_buff;
  1907. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  1908. "Called IOCTL_BCM_GET_DEVICE_DRIVER_INFO\n");
  1909. memset(&dev_info, 0, sizeof(dev_info));
  1910. dev_info.MaxRDMBufferSize = BUFFER_4K;
  1911. dev_info.u32DSDStartOffset = EEPROM_CALPARAM_START;
  1912. dev_info.u32RxAlignmentCorrection = 0;
  1913. dev_info.u32NVMType = ad->eNVMType;
  1914. dev_info.u32InterfaceType = BCM_USB;
  1915. if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer)))
  1916. return -EFAULT;
  1917. if (io_buff.OutputLength < sizeof(dev_info))
  1918. return -EINVAL;
  1919. if (copy_to_user(io_buff.OutputBuffer, &dev_info, sizeof(dev_info)))
  1920. return -EFAULT;
  1921. return STATUS_SUCCESS;
  1922. }
  1923. static int bcm_char_ioctl_time_since_net_entry(void __user *argp,
  1924. struct bcm_mini_adapter *ad)
  1925. {
  1926. struct bcm_time_elapsed time_elapsed_since_net_entry = {0};
  1927. struct bcm_ioctl_buffer io_buff;
  1928. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  1929. "IOCTL_BCM_TIME_SINCE_NET_ENTRY called");
  1930. if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer)))
  1931. return -EFAULT;
  1932. if (io_buff.OutputLength < sizeof(struct bcm_time_elapsed))
  1933. return -EINVAL;
  1934. time_elapsed_since_net_entry.ul64TimeElapsedSinceNetEntry =
  1935. get_seconds() - ad->liTimeSinceLastNetEntry;
  1936. if (copy_to_user(io_buff.OutputBuffer, &time_elapsed_since_net_entry,
  1937. sizeof(struct bcm_time_elapsed)))
  1938. return -EFAULT;
  1939. return STATUS_SUCCESS;
  1940. }
  1941. static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
  1942. {
  1943. struct bcm_tarang_data *tarang = filp->private_data;
  1944. void __user *argp = (void __user *)arg;
  1945. struct bcm_mini_adapter *ad = tarang->Adapter;
  1946. INT status = STATUS_FAILURE;
  1947. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  1948. "Parameters Passed to control IOCTL cmd=0x%X arg=0x%lX",
  1949. cmd, arg);
  1950. if (_IOC_TYPE(cmd) != BCM_IOCTL)
  1951. return -EFAULT;
  1952. if (_IOC_DIR(cmd) & _IOC_READ)
  1953. status = !access_ok(VERIFY_WRITE, argp, _IOC_SIZE(cmd));
  1954. else if (_IOC_DIR(cmd) & _IOC_WRITE)
  1955. status = !access_ok(VERIFY_READ, argp, _IOC_SIZE(cmd));
  1956. else if (_IOC_NONE == (_IOC_DIR(cmd) & _IOC_NONE))
  1957. status = STATUS_SUCCESS;
  1958. if (status)
  1959. return -EFAULT;
  1960. if (ad->device_removed)
  1961. return -EFAULT;
  1962. if (false == ad->fw_download_done) {
  1963. switch (cmd) {
  1964. case IOCTL_MAC_ADDR_REQ:
  1965. case IOCTL_LINK_REQ:
  1966. case IOCTL_CM_REQUEST:
  1967. case IOCTL_SS_INFO_REQ:
  1968. case IOCTL_SEND_CONTROL_MESSAGE:
  1969. case IOCTL_IDLE_REQ:
  1970. case IOCTL_BCM_GPIO_SET_REQUEST:
  1971. case IOCTL_BCM_GPIO_STATUS_REQUEST:
  1972. return -EACCES;
  1973. default:
  1974. break;
  1975. }
  1976. }
  1977. status = vendorextnIoctl(ad, cmd, arg);
  1978. if (status != CONTINUE_COMMON_PATH)
  1979. return status;
  1980. switch (cmd) {
  1981. /* Rdms for Swin Idle... */
  1982. case IOCTL_BCM_REGISTER_READ_PRIVATE:
  1983. status = bcm_char_ioctl_reg_read_private(argp, ad);
  1984. return status;
  1985. case IOCTL_BCM_REGISTER_WRITE_PRIVATE:
  1986. status = bcm_char_ioctl_reg_write_private(argp, ad);
  1987. return status;
  1988. case IOCTL_BCM_REGISTER_READ:
  1989. case IOCTL_BCM_EEPROM_REGISTER_READ:
  1990. status = bcm_char_ioctl_eeprom_reg_read(argp, ad);
  1991. return status;
  1992. case IOCTL_BCM_REGISTER_WRITE:
  1993. case IOCTL_BCM_EEPROM_REGISTER_WRITE:
  1994. status = bcm_char_ioctl_eeprom_reg_write(argp, ad, cmd);
  1995. return status;
  1996. case IOCTL_BCM_GPIO_SET_REQUEST:
  1997. status = bcm_char_ioctl_gpio_set_request(argp, ad);
  1998. return status;
  1999. case BCM_LED_THREAD_STATE_CHANGE_REQ:
  2000. status = bcm_char_ioctl_led_thread_state_change_req(argp,
  2001. ad);
  2002. return status;
  2003. case IOCTL_BCM_GPIO_STATUS_REQUEST:
  2004. status = bcm_char_ioctl_gpio_status_request(argp, ad);
  2005. return status;
  2006. case IOCTL_BCM_GPIO_MULTI_REQUEST:
  2007. status = bcm_char_ioctl_gpio_multi_request(argp, ad);
  2008. return status;
  2009. case IOCTL_BCM_GPIO_MODE_REQUEST:
  2010. status = bcm_char_ioctl_gpio_mode_request(argp, ad);
  2011. return status;
  2012. case IOCTL_MAC_ADDR_REQ:
  2013. case IOCTL_LINK_REQ:
  2014. case IOCTL_CM_REQUEST:
  2015. case IOCTL_SS_INFO_REQ:
  2016. case IOCTL_SEND_CONTROL_MESSAGE:
  2017. case IOCTL_IDLE_REQ:
  2018. status = bcm_char_ioctl_misc_request(argp, ad);
  2019. return status;
  2020. case IOCTL_BCM_BUFFER_DOWNLOAD_START:
  2021. status = bcm_char_ioctl_buffer_download_start(ad);
  2022. return status;
  2023. case IOCTL_BCM_BUFFER_DOWNLOAD:
  2024. status = bcm_char_ioctl_buffer_download(argp, ad);
  2025. return status;
  2026. case IOCTL_BCM_BUFFER_DOWNLOAD_STOP:
  2027. status = bcm_char_ioctl_buffer_download_stop(argp, ad);
  2028. return status;
  2029. case IOCTL_BE_BUCKET_SIZE:
  2030. status = 0;
  2031. if (get_user(ad->BEBucketSize,
  2032. (unsigned long __user *)arg))
  2033. status = -EFAULT;
  2034. break;
  2035. case IOCTL_RTPS_BUCKET_SIZE:
  2036. status = 0;
  2037. if (get_user(ad->rtPSBucketSize,
  2038. (unsigned long __user *)arg))
  2039. status = -EFAULT;
  2040. break;
  2041. case IOCTL_CHIP_RESET:
  2042. status = bcm_char_ioctl_chip_reset(ad);
  2043. return status;
  2044. case IOCTL_QOS_THRESHOLD:
  2045. status = bcm_char_ioctl_qos_threshold(arg, ad);
  2046. return status;
  2047. case IOCTL_DUMP_PACKET_INFO:
  2048. DumpPackInfo(ad);
  2049. DumpPhsRules(&ad->stBCMPhsContext);
  2050. status = STATUS_SUCCESS;
  2051. break;
  2052. case IOCTL_GET_PACK_INFO:
  2053. if (copy_to_user(argp, &ad->PackInfo,
  2054. sizeof(struct bcm_packet_info)*NO_OF_QUEUES))
  2055. return -EFAULT;
  2056. status = STATUS_SUCCESS;
  2057. break;
  2058. case IOCTL_BCM_SWITCH_TRANSFER_MODE:
  2059. status = bcm_char_ioctl_switch_transfer_mode(argp, ad);
  2060. return status;
  2061. case IOCTL_BCM_GET_DRIVER_VERSION:
  2062. status = bcm_char_ioctl_get_driver_version(argp);
  2063. return status;
  2064. case IOCTL_BCM_GET_CURRENT_STATUS:
  2065. status = bcm_char_ioctl_get_current_status(argp, ad);
  2066. return status;
  2067. case IOCTL_BCM_SET_MAC_TRACING:
  2068. status = bcm_char_ioctl_set_mac_tracing(argp, ad);
  2069. return status;
  2070. case IOCTL_BCM_GET_DSX_INDICATION:
  2071. status = bcm_char_ioctl_get_dsx_indication(argp, ad);
  2072. return status;
  2073. case IOCTL_BCM_GET_HOST_MIBS:
  2074. status = bcm_char_ioctl_get_host_mibs(argp, ad, tarang);
  2075. return status;
  2076. case IOCTL_BCM_WAKE_UP_DEVICE_FROM_IDLE:
  2077. if ((false == ad->bTriedToWakeUpFromlowPowerMode) &&
  2078. (TRUE == ad->IdleMode)) {
  2079. ad->usIdleModePattern = ABORT_IDLE_MODE;
  2080. ad->bWakeUpDevice = TRUE;
  2081. wake_up(&ad->process_rx_cntrlpkt);
  2082. }
  2083. status = STATUS_SUCCESS;
  2084. break;
  2085. case IOCTL_BCM_BULK_WRM:
  2086. status = bcm_char_ioctl_bulk_wrm(argp, ad, cmd);
  2087. return status;
  2088. case IOCTL_BCM_GET_NVM_SIZE:
  2089. status = bcm_char_ioctl_get_nvm_size(argp, ad);
  2090. return status;
  2091. case IOCTL_BCM_CAL_INIT:
  2092. status = bcm_char_ioctl_cal_init(argp, ad);
  2093. return status;
  2094. case IOCTL_BCM_SET_DEBUG:
  2095. status = bcm_char_ioctl_set_debug(argp, ad);
  2096. return status;
  2097. case IOCTL_BCM_NVM_READ:
  2098. case IOCTL_BCM_NVM_WRITE:
  2099. status = bcm_char_ioctl_nvm_rw(argp, ad, cmd);
  2100. return status;
  2101. case IOCTL_BCM_FLASH2X_SECTION_READ:
  2102. status = bcm_char_ioctl_flash2x_section_read(argp, ad);
  2103. return status;
  2104. case IOCTL_BCM_FLASH2X_SECTION_WRITE:
  2105. status = bcm_char_ioctl_flash2x_section_write(argp, ad);
  2106. return status;
  2107. case IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP:
  2108. status = bcm_char_ioctl_flash2x_section_bitmap(argp, ad);
  2109. return status;
  2110. case IOCTL_BCM_SET_ACTIVE_SECTION:
  2111. status = bcm_char_ioctl_set_active_section(argp, ad);
  2112. return status;
  2113. case IOCTL_BCM_IDENTIFY_ACTIVE_SECTION:
  2114. /* Right Now we are taking care of only DSD */
  2115. ad->bAllDSDWriteAllow = false;
  2116. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  2117. "IOCTL_BCM_IDENTIFY_ACTIVE_SECTION called");
  2118. status = STATUS_SUCCESS;
  2119. break;
  2120. case IOCTL_BCM_COPY_SECTION:
  2121. status = bcm_char_ioctl_copy_section(argp, ad);
  2122. return status;
  2123. case IOCTL_BCM_GET_FLASH_CS_INFO:
  2124. status = bcm_char_ioctl_get_flash_cs_info(argp, ad);
  2125. return status;
  2126. case IOCTL_BCM_SELECT_DSD:
  2127. status = bcm_char_ioctl_select_dsd(argp, ad);
  2128. return status;
  2129. case IOCTL_BCM_NVM_RAW_READ:
  2130. status = bcm_char_ioctl_nvm_raw_read(argp, ad);
  2131. return status;
  2132. case IOCTL_BCM_CNTRLMSG_MASK:
  2133. status = bcm_char_ioctl_cntrlmsg_mask(argp, ad, tarang);
  2134. return status;
  2135. case IOCTL_BCM_GET_DEVICE_DRIVER_INFO:
  2136. status = bcm_char_ioctl_get_device_driver_info(argp, ad);
  2137. return status;
  2138. case IOCTL_BCM_TIME_SINCE_NET_ENTRY:
  2139. status = bcm_char_ioctl_time_since_net_entry(argp, ad);
  2140. return status;
  2141. case IOCTL_CLOSE_NOTIFICATION:
  2142. BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
  2143. "IOCTL_CLOSE_NOTIFICATION");
  2144. break;
  2145. default:
  2146. pr_info(DRV_NAME ": unknown ioctl cmd=%#x\n", cmd);
  2147. status = STATUS_FAILURE;
  2148. break;
  2149. }
  2150. return status;
  2151. }
  2152. static const struct file_operations bcm_fops = {
  2153. .owner = THIS_MODULE,
  2154. .open = bcm_char_open,
  2155. .release = bcm_char_release,
  2156. .read = bcm_char_read,
  2157. .unlocked_ioctl = bcm_char_ioctl,
  2158. .llseek = no_llseek,
  2159. };
  2160. int register_control_device_interface(struct bcm_mini_adapter *ad)
  2161. {
  2162. if (ad->major > 0)
  2163. return ad->major;
  2164. ad->major = register_chrdev(0, DEV_NAME, &bcm_fops);
  2165. if (ad->major < 0) {
  2166. pr_err(DRV_NAME ": could not created character device\n");
  2167. return ad->major;
  2168. }
  2169. ad->pstCreatedClassDevice = device_create(bcm_class, NULL,
  2170. MKDEV(ad->major, 0),
  2171. ad, DEV_NAME);
  2172. if (IS_ERR(ad->pstCreatedClassDevice)) {
  2173. pr_err(DRV_NAME ": class device create failed\n");
  2174. unregister_chrdev(ad->major, DEV_NAME);
  2175. return PTR_ERR(ad->pstCreatedClassDevice);
  2176. }
  2177. return 0;
  2178. }
  2179. void unregister_control_device_interface(struct bcm_mini_adapter *ad)
  2180. {
  2181. if (ad->major > 0) {
  2182. device_destroy(bcm_class, MKDEV(ad->major, 0));
  2183. unregister_chrdev(ad->major, DEV_NAME);
  2184. }
  2185. }