qed_iscsi.c 43 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460
  1. /* QLogic qed NIC Driver
  2. * Copyright (c) 2015-2017 QLogic Corporation
  3. *
  4. * This software is available to you under a choice of one of two
  5. * licenses. You may choose to be licensed under the terms of the GNU
  6. * General Public License (GPL) Version 2, available from the file
  7. * COPYING in the main directory of this source tree, or the
  8. * OpenIB.org BSD license below:
  9. *
  10. * Redistribution and use in source and binary forms, with or
  11. * without modification, are permitted provided that the following
  12. * conditions are met:
  13. *
  14. * - Redistributions of source code must retain the above
  15. * copyright notice, this list of conditions and the following
  16. * disclaimer.
  17. *
  18. * - Redistributions in binary form must reproduce the above
  19. * copyright notice, this list of conditions and the following
  20. * disclaimer in the documentation and /or other materials
  21. * provided with the distribution.
  22. *
  23. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  24. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  25. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  26. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  27. * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  28. * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  29. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  30. * SOFTWARE.
  31. */
  32. #include <linux/types.h>
  33. #include <asm/byteorder.h>
  34. #include <asm/param.h>
  35. #include <linux/delay.h>
  36. #include <linux/dma-mapping.h>
  37. #include <linux/etherdevice.h>
  38. #include <linux/interrupt.h>
  39. #include <linux/kernel.h>
  40. #include <linux/log2.h>
  41. #include <linux/module.h>
  42. #include <linux/pci.h>
  43. #include <linux/slab.h>
  44. #include <linux/stddef.h>
  45. #include <linux/string.h>
  46. #include <linux/workqueue.h>
  47. #include <linux/errno.h>
  48. #include <linux/list.h>
  49. #include <linux/spinlock.h>
  50. #include <linux/qed/qed_iscsi_if.h>
  51. #include "qed.h"
  52. #include "qed_cxt.h"
  53. #include "qed_dev_api.h"
  54. #include "qed_hsi.h"
  55. #include "qed_hw.h"
  56. #include "qed_int.h"
  57. #include "qed_iscsi.h"
  58. #include "qed_ll2.h"
  59. #include "qed_mcp.h"
  60. #include "qed_sp.h"
  61. #include "qed_sriov.h"
  62. #include "qed_reg_addr.h"
  63. static int
  64. qed_iscsi_async_event(struct qed_hwfn *p_hwfn,
  65. u8 fw_event_code,
  66. u16 echo, union event_ring_data *data, u8 fw_return_code)
  67. {
  68. if (p_hwfn->p_iscsi_info->event_cb) {
  69. struct qed_iscsi_info *p_iscsi = p_hwfn->p_iscsi_info;
  70. return p_iscsi->event_cb(p_iscsi->event_context,
  71. fw_event_code, data);
  72. } else {
  73. DP_NOTICE(p_hwfn, "iSCSI async completion is not set\n");
  74. return -EINVAL;
  75. }
  76. }
  77. struct qed_iscsi_conn {
  78. struct list_head list_entry;
  79. bool free_on_delete;
  80. u16 conn_id;
  81. u32 icid;
  82. u32 fw_cid;
  83. u8 layer_code;
  84. u8 offl_flags;
  85. u8 connect_mode;
  86. u32 initial_ack;
  87. dma_addr_t sq_pbl_addr;
  88. struct qed_chain r2tq;
  89. struct qed_chain xhq;
  90. struct qed_chain uhq;
  91. struct tcp_upload_params *tcp_upload_params_virt_addr;
  92. dma_addr_t tcp_upload_params_phys_addr;
  93. struct scsi_terminate_extra_params *queue_cnts_virt_addr;
  94. dma_addr_t queue_cnts_phys_addr;
  95. dma_addr_t syn_phy_addr;
  96. u16 syn_ip_payload_length;
  97. u8 local_mac[6];
  98. u8 remote_mac[6];
  99. u16 vlan_id;
  100. u8 tcp_flags;
  101. u8 ip_version;
  102. u32 remote_ip[4];
  103. u32 local_ip[4];
  104. u8 ka_max_probe_cnt;
  105. u8 dup_ack_theshold;
  106. u32 rcv_next;
  107. u32 snd_una;
  108. u32 snd_next;
  109. u32 snd_max;
  110. u32 snd_wnd;
  111. u32 rcv_wnd;
  112. u32 snd_wl1;
  113. u32 cwnd;
  114. u32 ss_thresh;
  115. u16 srtt;
  116. u16 rtt_var;
  117. u32 ts_time;
  118. u32 ts_recent;
  119. u32 ts_recent_age;
  120. u32 total_rt;
  121. u32 ka_timeout_delta;
  122. u32 rt_timeout_delta;
  123. u8 dup_ack_cnt;
  124. u8 snd_wnd_probe_cnt;
  125. u8 ka_probe_cnt;
  126. u8 rt_cnt;
  127. u32 flow_label;
  128. u32 ka_timeout;
  129. u32 ka_interval;
  130. u32 max_rt_time;
  131. u32 initial_rcv_wnd;
  132. u8 ttl;
  133. u8 tos_or_tc;
  134. u16 remote_port;
  135. u16 local_port;
  136. u16 mss;
  137. u8 snd_wnd_scale;
  138. u8 rcv_wnd_scale;
  139. u32 ts_ticks_per_second;
  140. u16 da_timeout_value;
  141. u8 ack_frequency;
  142. u8 update_flag;
  143. u8 default_cq;
  144. u32 max_seq_size;
  145. u32 max_recv_pdu_length;
  146. u32 max_send_pdu_length;
  147. u32 first_seq_length;
  148. u32 exp_stat_sn;
  149. u32 stat_sn;
  150. u16 physical_q0;
  151. u16 physical_q1;
  152. u8 abortive_dsconnect;
  153. };
  154. static int
  155. qed_sp_iscsi_func_start(struct qed_hwfn *p_hwfn,
  156. enum spq_mode comp_mode,
  157. struct qed_spq_comp_cb *p_comp_addr,
  158. void *event_context, iscsi_event_cb_t async_event_cb)
  159. {
  160. struct iscsi_init_ramrod_params *p_ramrod = NULL;
  161. struct scsi_init_func_queues *p_queue = NULL;
  162. struct qed_iscsi_pf_params *p_params = NULL;
  163. struct iscsi_spe_func_init *p_init = NULL;
  164. struct qed_spq_entry *p_ent = NULL;
  165. struct qed_sp_init_data init_data;
  166. int rc = 0;
  167. u32 dval;
  168. u16 val;
  169. u8 i;
  170. /* Get SPQ entry */
  171. memset(&init_data, 0, sizeof(init_data));
  172. init_data.cid = qed_spq_get_cid(p_hwfn);
  173. init_data.opaque_fid = p_hwfn->hw_info.opaque_fid;
  174. init_data.comp_mode = comp_mode;
  175. init_data.p_comp_data = p_comp_addr;
  176. rc = qed_sp_init_request(p_hwfn, &p_ent,
  177. ISCSI_RAMROD_CMD_ID_INIT_FUNC,
  178. PROTOCOLID_ISCSI, &init_data);
  179. if (rc)
  180. return rc;
  181. p_ramrod = &p_ent->ramrod.iscsi_init;
  182. p_init = &p_ramrod->iscsi_init_spe;
  183. p_params = &p_hwfn->pf_params.iscsi_pf_params;
  184. p_queue = &p_init->q_params;
  185. /* Sanity */
  186. if (p_params->num_queues > p_hwfn->hw_info.feat_num[QED_ISCSI_CQ]) {
  187. DP_ERR(p_hwfn,
  188. "Cannot satisfy CQ amount. Queues requested %d, CQs available %d. Aborting function start\n",
  189. p_params->num_queues,
  190. p_hwfn->hw_info.feat_num[QED_ISCSI_CQ]);
  191. return -EINVAL;
  192. }
  193. SET_FIELD(p_init->hdr.flags,
  194. ISCSI_SLOW_PATH_HDR_LAYER_CODE, ISCSI_SLOW_PATH_LAYER_CODE);
  195. p_init->hdr.op_code = ISCSI_RAMROD_CMD_ID_INIT_FUNC;
  196. val = p_params->half_way_close_timeout;
  197. p_init->half_way_close_timeout = cpu_to_le16(val);
  198. p_init->num_sq_pages_in_ring = p_params->num_sq_pages_in_ring;
  199. p_init->num_r2tq_pages_in_ring = p_params->num_r2tq_pages_in_ring;
  200. p_init->num_uhq_pages_in_ring = p_params->num_uhq_pages_in_ring;
  201. p_init->ooo_enable = p_params->ooo_enable;
  202. p_init->ll2_rx_queue_id = p_hwfn->hw_info.resc_start[QED_LL2_QUEUE] +
  203. p_params->ll2_ooo_queue_id;
  204. p_init->func_params.log_page_size = p_params->log_page_size;
  205. val = p_params->num_tasks;
  206. p_init->func_params.num_tasks = cpu_to_le16(val);
  207. p_init->debug_mode.flags = p_params->debug_mode;
  208. DMA_REGPAIR_LE(p_queue->glbl_q_params_addr,
  209. p_params->glbl_q_params_addr);
  210. val = p_params->cq_num_entries;
  211. p_queue->cq_num_entries = cpu_to_le16(val);
  212. val = p_params->cmdq_num_entries;
  213. p_queue->cmdq_num_entries = cpu_to_le16(val);
  214. p_queue->num_queues = p_params->num_queues;
  215. dval = (u8)p_hwfn->hw_info.resc_start[QED_CMDQS_CQS];
  216. p_queue->queue_relative_offset = (u8)dval;
  217. p_queue->cq_sb_pi = p_params->gl_rq_pi;
  218. p_queue->cmdq_sb_pi = p_params->gl_cmd_pi;
  219. for (i = 0; i < p_params->num_queues; i++) {
  220. val = qed_get_igu_sb_id(p_hwfn, i);
  221. p_queue->cq_cmdq_sb_num_arr[i] = cpu_to_le16(val);
  222. }
  223. p_queue->bdq_resource_id = (u8)RESC_START(p_hwfn, QED_BDQ);
  224. DMA_REGPAIR_LE(p_queue->bdq_pbl_base_address[BDQ_ID_RQ],
  225. p_params->bdq_pbl_base_addr[BDQ_ID_RQ]);
  226. p_queue->bdq_pbl_num_entries[BDQ_ID_RQ] =
  227. p_params->bdq_pbl_num_entries[BDQ_ID_RQ];
  228. val = p_params->bdq_xoff_threshold[BDQ_ID_RQ];
  229. p_queue->bdq_xoff_threshold[BDQ_ID_RQ] = cpu_to_le16(val);
  230. val = p_params->bdq_xon_threshold[BDQ_ID_RQ];
  231. p_queue->bdq_xon_threshold[BDQ_ID_RQ] = cpu_to_le16(val);
  232. DMA_REGPAIR_LE(p_queue->bdq_pbl_base_address[BDQ_ID_IMM_DATA],
  233. p_params->bdq_pbl_base_addr[BDQ_ID_IMM_DATA]);
  234. p_queue->bdq_pbl_num_entries[BDQ_ID_IMM_DATA] =
  235. p_params->bdq_pbl_num_entries[BDQ_ID_IMM_DATA];
  236. val = p_params->bdq_xoff_threshold[BDQ_ID_IMM_DATA];
  237. p_queue->bdq_xoff_threshold[BDQ_ID_IMM_DATA] = cpu_to_le16(val);
  238. val = p_params->bdq_xon_threshold[BDQ_ID_IMM_DATA];
  239. p_queue->bdq_xon_threshold[BDQ_ID_IMM_DATA] = cpu_to_le16(val);
  240. val = p_params->rq_buffer_size;
  241. p_queue->rq_buffer_size = cpu_to_le16(val);
  242. if (p_params->is_target) {
  243. SET_FIELD(p_queue->q_validity,
  244. SCSI_INIT_FUNC_QUEUES_RQ_VALID, 1);
  245. if (p_queue->bdq_pbl_num_entries[BDQ_ID_IMM_DATA])
  246. SET_FIELD(p_queue->q_validity,
  247. SCSI_INIT_FUNC_QUEUES_IMM_DATA_VALID, 1);
  248. SET_FIELD(p_queue->q_validity,
  249. SCSI_INIT_FUNC_QUEUES_CMD_VALID, 1);
  250. } else {
  251. SET_FIELD(p_queue->q_validity,
  252. SCSI_INIT_FUNC_QUEUES_RQ_VALID, 1);
  253. }
  254. p_ramrod->tcp_init.two_msl_timer = cpu_to_le32(p_params->two_msl_timer);
  255. val = p_params->tx_sws_timer;
  256. p_ramrod->tcp_init.tx_sws_timer = cpu_to_le16(val);
  257. p_ramrod->tcp_init.maxfinrt = p_params->max_fin_rt;
  258. p_hwfn->p_iscsi_info->event_context = event_context;
  259. p_hwfn->p_iscsi_info->event_cb = async_event_cb;
  260. qed_spq_register_async_cb(p_hwfn, PROTOCOLID_ISCSI,
  261. qed_iscsi_async_event);
  262. return qed_spq_post(p_hwfn, p_ent, NULL);
  263. }
  264. static int qed_sp_iscsi_conn_offload(struct qed_hwfn *p_hwfn,
  265. struct qed_iscsi_conn *p_conn,
  266. enum spq_mode comp_mode,
  267. struct qed_spq_comp_cb *p_comp_addr)
  268. {
  269. struct iscsi_spe_conn_offload *p_ramrod = NULL;
  270. struct tcp_offload_params_opt2 *p_tcp2 = NULL;
  271. struct tcp_offload_params *p_tcp = NULL;
  272. struct qed_spq_entry *p_ent = NULL;
  273. struct qed_sp_init_data init_data;
  274. dma_addr_t r2tq_pbl_addr;
  275. dma_addr_t xhq_pbl_addr;
  276. dma_addr_t uhq_pbl_addr;
  277. u16 physical_q;
  278. int rc = 0;
  279. u32 dval;
  280. u16 wval;
  281. u8 i;
  282. u16 *p;
  283. /* Get SPQ entry */
  284. memset(&init_data, 0, sizeof(init_data));
  285. init_data.cid = p_conn->icid;
  286. init_data.opaque_fid = p_hwfn->hw_info.opaque_fid;
  287. init_data.comp_mode = comp_mode;
  288. init_data.p_comp_data = p_comp_addr;
  289. rc = qed_sp_init_request(p_hwfn, &p_ent,
  290. ISCSI_RAMROD_CMD_ID_OFFLOAD_CONN,
  291. PROTOCOLID_ISCSI, &init_data);
  292. if (rc)
  293. return rc;
  294. p_ramrod = &p_ent->ramrod.iscsi_conn_offload;
  295. /* Transmission PQ is the first of the PF */
  296. physical_q = qed_get_cm_pq_idx(p_hwfn, PQ_FLAGS_OFLD);
  297. p_conn->physical_q0 = cpu_to_le16(physical_q);
  298. p_ramrod->iscsi.physical_q0 = cpu_to_le16(physical_q);
  299. /* iSCSI Pure-ACK PQ */
  300. physical_q = qed_get_cm_pq_idx(p_hwfn, PQ_FLAGS_ACK);
  301. p_conn->physical_q1 = cpu_to_le16(physical_q);
  302. p_ramrod->iscsi.physical_q1 = cpu_to_le16(physical_q);
  303. p_ramrod->hdr.op_code = ISCSI_RAMROD_CMD_ID_OFFLOAD_CONN;
  304. SET_FIELD(p_ramrod->hdr.flags, ISCSI_SLOW_PATH_HDR_LAYER_CODE,
  305. p_conn->layer_code);
  306. p_ramrod->conn_id = cpu_to_le16(p_conn->conn_id);
  307. p_ramrod->fw_cid = cpu_to_le32(p_conn->icid);
  308. DMA_REGPAIR_LE(p_ramrod->iscsi.sq_pbl_addr, p_conn->sq_pbl_addr);
  309. r2tq_pbl_addr = qed_chain_get_pbl_phys(&p_conn->r2tq);
  310. DMA_REGPAIR_LE(p_ramrod->iscsi.r2tq_pbl_addr, r2tq_pbl_addr);
  311. xhq_pbl_addr = qed_chain_get_pbl_phys(&p_conn->xhq);
  312. DMA_REGPAIR_LE(p_ramrod->iscsi.xhq_pbl_addr, xhq_pbl_addr);
  313. uhq_pbl_addr = qed_chain_get_pbl_phys(&p_conn->uhq);
  314. DMA_REGPAIR_LE(p_ramrod->iscsi.uhq_pbl_addr, uhq_pbl_addr);
  315. p_ramrod->iscsi.initial_ack = cpu_to_le32(p_conn->initial_ack);
  316. p_ramrod->iscsi.flags = p_conn->offl_flags;
  317. p_ramrod->iscsi.default_cq = p_conn->default_cq;
  318. p_ramrod->iscsi.stat_sn = cpu_to_le32(p_conn->stat_sn);
  319. if (!GET_FIELD(p_ramrod->iscsi.flags,
  320. ISCSI_CONN_OFFLOAD_PARAMS_TCP_ON_CHIP_1B)) {
  321. p_tcp = &p_ramrod->tcp;
  322. p = (u16 *)p_conn->local_mac;
  323. p_tcp->local_mac_addr_hi = swab16(get_unaligned(p));
  324. p_tcp->local_mac_addr_mid = swab16(get_unaligned(p + 1));
  325. p_tcp->local_mac_addr_lo = swab16(get_unaligned(p + 2));
  326. p = (u16 *)p_conn->remote_mac;
  327. p_tcp->remote_mac_addr_hi = swab16(get_unaligned(p));
  328. p_tcp->remote_mac_addr_mid = swab16(get_unaligned(p + 1));
  329. p_tcp->remote_mac_addr_lo = swab16(get_unaligned(p + 2));
  330. p_tcp->vlan_id = cpu_to_le16(p_conn->vlan_id);
  331. p_tcp->flags = p_conn->tcp_flags;
  332. p_tcp->ip_version = p_conn->ip_version;
  333. for (i = 0; i < 4; i++) {
  334. dval = p_conn->remote_ip[i];
  335. p_tcp->remote_ip[i] = cpu_to_le32(dval);
  336. dval = p_conn->local_ip[i];
  337. p_tcp->local_ip[i] = cpu_to_le32(dval);
  338. }
  339. p_tcp->ka_max_probe_cnt = p_conn->ka_max_probe_cnt;
  340. p_tcp->dup_ack_theshold = p_conn->dup_ack_theshold;
  341. p_tcp->rcv_next = cpu_to_le32(p_conn->rcv_next);
  342. p_tcp->snd_una = cpu_to_le32(p_conn->snd_una);
  343. p_tcp->snd_next = cpu_to_le32(p_conn->snd_next);
  344. p_tcp->snd_max = cpu_to_le32(p_conn->snd_max);
  345. p_tcp->snd_wnd = cpu_to_le32(p_conn->snd_wnd);
  346. p_tcp->rcv_wnd = cpu_to_le32(p_conn->rcv_wnd);
  347. p_tcp->snd_wl1 = cpu_to_le32(p_conn->snd_wl1);
  348. p_tcp->cwnd = cpu_to_le32(p_conn->cwnd);
  349. p_tcp->ss_thresh = cpu_to_le32(p_conn->ss_thresh);
  350. p_tcp->srtt = cpu_to_le16(p_conn->srtt);
  351. p_tcp->rtt_var = cpu_to_le16(p_conn->rtt_var);
  352. p_tcp->ts_recent = cpu_to_le32(p_conn->ts_recent);
  353. p_tcp->ts_recent_age = cpu_to_le32(p_conn->ts_recent_age);
  354. p_tcp->total_rt = cpu_to_le32(p_conn->total_rt);
  355. dval = p_conn->ka_timeout_delta;
  356. p_tcp->ka_timeout_delta = cpu_to_le32(dval);
  357. dval = p_conn->rt_timeout_delta;
  358. p_tcp->rt_timeout_delta = cpu_to_le32(dval);
  359. p_tcp->dup_ack_cnt = p_conn->dup_ack_cnt;
  360. p_tcp->snd_wnd_probe_cnt = p_conn->snd_wnd_probe_cnt;
  361. p_tcp->ka_probe_cnt = p_conn->ka_probe_cnt;
  362. p_tcp->rt_cnt = p_conn->rt_cnt;
  363. p_tcp->flow_label = cpu_to_le32(p_conn->flow_label);
  364. p_tcp->ka_timeout = cpu_to_le32(p_conn->ka_timeout);
  365. p_tcp->ka_interval = cpu_to_le32(p_conn->ka_interval);
  366. p_tcp->max_rt_time = cpu_to_le32(p_conn->max_rt_time);
  367. dval = p_conn->initial_rcv_wnd;
  368. p_tcp->initial_rcv_wnd = cpu_to_le32(dval);
  369. p_tcp->ttl = p_conn->ttl;
  370. p_tcp->tos_or_tc = p_conn->tos_or_tc;
  371. p_tcp->remote_port = cpu_to_le16(p_conn->remote_port);
  372. p_tcp->local_port = cpu_to_le16(p_conn->local_port);
  373. p_tcp->mss = cpu_to_le16(p_conn->mss);
  374. p_tcp->snd_wnd_scale = p_conn->snd_wnd_scale;
  375. p_tcp->rcv_wnd_scale = p_conn->rcv_wnd_scale;
  376. wval = p_conn->da_timeout_value;
  377. p_tcp->da_timeout_value = cpu_to_le16(wval);
  378. p_tcp->ack_frequency = p_conn->ack_frequency;
  379. p_tcp->connect_mode = p_conn->connect_mode;
  380. } else {
  381. p_tcp2 =
  382. &((struct iscsi_spe_conn_offload_option2 *)p_ramrod)->tcp;
  383. p = (u16 *)p_conn->local_mac;
  384. p_tcp2->local_mac_addr_hi = swab16(get_unaligned(p));
  385. p_tcp2->local_mac_addr_mid = swab16(get_unaligned(p + 1));
  386. p_tcp2->local_mac_addr_lo = swab16(get_unaligned(p + 2));
  387. p = (u16 *)p_conn->remote_mac;
  388. p_tcp2->remote_mac_addr_hi = swab16(get_unaligned(p));
  389. p_tcp2->remote_mac_addr_mid = swab16(get_unaligned(p + 1));
  390. p_tcp2->remote_mac_addr_lo = swab16(get_unaligned(p + 2));
  391. p_tcp2->vlan_id = cpu_to_le16(p_conn->vlan_id);
  392. p_tcp2->flags = p_conn->tcp_flags;
  393. p_tcp2->ip_version = p_conn->ip_version;
  394. for (i = 0; i < 4; i++) {
  395. dval = p_conn->remote_ip[i];
  396. p_tcp2->remote_ip[i] = cpu_to_le32(dval);
  397. dval = p_conn->local_ip[i];
  398. p_tcp2->local_ip[i] = cpu_to_le32(dval);
  399. }
  400. p_tcp2->flow_label = cpu_to_le32(p_conn->flow_label);
  401. p_tcp2->ttl = p_conn->ttl;
  402. p_tcp2->tos_or_tc = p_conn->tos_or_tc;
  403. p_tcp2->remote_port = cpu_to_le16(p_conn->remote_port);
  404. p_tcp2->local_port = cpu_to_le16(p_conn->local_port);
  405. p_tcp2->mss = cpu_to_le16(p_conn->mss);
  406. p_tcp2->rcv_wnd_scale = p_conn->rcv_wnd_scale;
  407. p_tcp2->connect_mode = p_conn->connect_mode;
  408. wval = p_conn->syn_ip_payload_length;
  409. p_tcp2->syn_ip_payload_length = cpu_to_le16(wval);
  410. p_tcp2->syn_phy_addr_lo = DMA_LO_LE(p_conn->syn_phy_addr);
  411. p_tcp2->syn_phy_addr_hi = DMA_HI_LE(p_conn->syn_phy_addr);
  412. }
  413. return qed_spq_post(p_hwfn, p_ent, NULL);
  414. }
  415. static int qed_sp_iscsi_conn_update(struct qed_hwfn *p_hwfn,
  416. struct qed_iscsi_conn *p_conn,
  417. enum spq_mode comp_mode,
  418. struct qed_spq_comp_cb *p_comp_addr)
  419. {
  420. struct iscsi_conn_update_ramrod_params *p_ramrod = NULL;
  421. struct qed_spq_entry *p_ent = NULL;
  422. struct qed_sp_init_data init_data;
  423. int rc = -EINVAL;
  424. u32 dval;
  425. /* Get SPQ entry */
  426. memset(&init_data, 0, sizeof(init_data));
  427. init_data.cid = p_conn->icid;
  428. init_data.opaque_fid = p_hwfn->hw_info.opaque_fid;
  429. init_data.comp_mode = comp_mode;
  430. init_data.p_comp_data = p_comp_addr;
  431. rc = qed_sp_init_request(p_hwfn, &p_ent,
  432. ISCSI_RAMROD_CMD_ID_UPDATE_CONN,
  433. PROTOCOLID_ISCSI, &init_data);
  434. if (rc)
  435. return rc;
  436. p_ramrod = &p_ent->ramrod.iscsi_conn_update;
  437. p_ramrod->hdr.op_code = ISCSI_RAMROD_CMD_ID_UPDATE_CONN;
  438. SET_FIELD(p_ramrod->hdr.flags,
  439. ISCSI_SLOW_PATH_HDR_LAYER_CODE, p_conn->layer_code);
  440. p_ramrod->conn_id = cpu_to_le16(p_conn->conn_id);
  441. p_ramrod->fw_cid = cpu_to_le32(p_conn->icid);
  442. p_ramrod->flags = p_conn->update_flag;
  443. p_ramrod->max_seq_size = cpu_to_le32(p_conn->max_seq_size);
  444. dval = p_conn->max_recv_pdu_length;
  445. p_ramrod->max_recv_pdu_length = cpu_to_le32(dval);
  446. dval = p_conn->max_send_pdu_length;
  447. p_ramrod->max_send_pdu_length = cpu_to_le32(dval);
  448. dval = p_conn->first_seq_length;
  449. p_ramrod->first_seq_length = cpu_to_le32(dval);
  450. p_ramrod->exp_stat_sn = cpu_to_le32(p_conn->exp_stat_sn);
  451. return qed_spq_post(p_hwfn, p_ent, NULL);
  452. }
  453. static int
  454. qed_sp_iscsi_mac_update(struct qed_hwfn *p_hwfn,
  455. struct qed_iscsi_conn *p_conn,
  456. enum spq_mode comp_mode,
  457. struct qed_spq_comp_cb *p_comp_addr)
  458. {
  459. struct iscsi_spe_conn_mac_update *p_ramrod = NULL;
  460. struct qed_spq_entry *p_ent = NULL;
  461. struct qed_sp_init_data init_data;
  462. int rc = -EINVAL;
  463. u8 ucval;
  464. /* Get SPQ entry */
  465. memset(&init_data, 0, sizeof(init_data));
  466. init_data.cid = p_conn->icid;
  467. init_data.opaque_fid = p_hwfn->hw_info.opaque_fid;
  468. init_data.comp_mode = comp_mode;
  469. init_data.p_comp_data = p_comp_addr;
  470. rc = qed_sp_init_request(p_hwfn, &p_ent,
  471. ISCSI_RAMROD_CMD_ID_MAC_UPDATE,
  472. PROTOCOLID_ISCSI, &init_data);
  473. if (rc)
  474. return rc;
  475. p_ramrod = &p_ent->ramrod.iscsi_conn_mac_update;
  476. p_ramrod->hdr.op_code = ISCSI_RAMROD_CMD_ID_MAC_UPDATE;
  477. SET_FIELD(p_ramrod->hdr.flags,
  478. ISCSI_SLOW_PATH_HDR_LAYER_CODE, p_conn->layer_code);
  479. p_ramrod->conn_id = cpu_to_le16(p_conn->conn_id);
  480. p_ramrod->fw_cid = cpu_to_le32(p_conn->icid);
  481. ucval = p_conn->remote_mac[1];
  482. ((u8 *)(&p_ramrod->remote_mac_addr_hi))[0] = ucval;
  483. ucval = p_conn->remote_mac[0];
  484. ((u8 *)(&p_ramrod->remote_mac_addr_hi))[1] = ucval;
  485. ucval = p_conn->remote_mac[3];
  486. ((u8 *)(&p_ramrod->remote_mac_addr_mid))[0] = ucval;
  487. ucval = p_conn->remote_mac[2];
  488. ((u8 *)(&p_ramrod->remote_mac_addr_mid))[1] = ucval;
  489. ucval = p_conn->remote_mac[5];
  490. ((u8 *)(&p_ramrod->remote_mac_addr_lo))[0] = ucval;
  491. ucval = p_conn->remote_mac[4];
  492. ((u8 *)(&p_ramrod->remote_mac_addr_lo))[1] = ucval;
  493. return qed_spq_post(p_hwfn, p_ent, NULL);
  494. }
  495. static int qed_sp_iscsi_conn_terminate(struct qed_hwfn *p_hwfn,
  496. struct qed_iscsi_conn *p_conn,
  497. enum spq_mode comp_mode,
  498. struct qed_spq_comp_cb *p_comp_addr)
  499. {
  500. struct iscsi_spe_conn_termination *p_ramrod = NULL;
  501. struct qed_spq_entry *p_ent = NULL;
  502. struct qed_sp_init_data init_data;
  503. int rc = -EINVAL;
  504. /* Get SPQ entry */
  505. memset(&init_data, 0, sizeof(init_data));
  506. init_data.cid = p_conn->icid;
  507. init_data.opaque_fid = p_hwfn->hw_info.opaque_fid;
  508. init_data.comp_mode = comp_mode;
  509. init_data.p_comp_data = p_comp_addr;
  510. rc = qed_sp_init_request(p_hwfn, &p_ent,
  511. ISCSI_RAMROD_CMD_ID_TERMINATION_CONN,
  512. PROTOCOLID_ISCSI, &init_data);
  513. if (rc)
  514. return rc;
  515. p_ramrod = &p_ent->ramrod.iscsi_conn_terminate;
  516. p_ramrod->hdr.op_code = ISCSI_RAMROD_CMD_ID_TERMINATION_CONN;
  517. SET_FIELD(p_ramrod->hdr.flags,
  518. ISCSI_SLOW_PATH_HDR_LAYER_CODE, p_conn->layer_code);
  519. p_ramrod->conn_id = cpu_to_le16(p_conn->conn_id);
  520. p_ramrod->fw_cid = cpu_to_le32(p_conn->icid);
  521. p_ramrod->abortive = p_conn->abortive_dsconnect;
  522. DMA_REGPAIR_LE(p_ramrod->query_params_addr,
  523. p_conn->tcp_upload_params_phys_addr);
  524. DMA_REGPAIR_LE(p_ramrod->queue_cnts_addr, p_conn->queue_cnts_phys_addr);
  525. return qed_spq_post(p_hwfn, p_ent, NULL);
  526. }
  527. static int qed_sp_iscsi_conn_clear_sq(struct qed_hwfn *p_hwfn,
  528. struct qed_iscsi_conn *p_conn,
  529. enum spq_mode comp_mode,
  530. struct qed_spq_comp_cb *p_comp_addr)
  531. {
  532. struct iscsi_slow_path_hdr *p_ramrod = NULL;
  533. struct qed_spq_entry *p_ent = NULL;
  534. struct qed_sp_init_data init_data;
  535. int rc = -EINVAL;
  536. /* Get SPQ entry */
  537. memset(&init_data, 0, sizeof(init_data));
  538. init_data.cid = p_conn->icid;
  539. init_data.opaque_fid = p_hwfn->hw_info.opaque_fid;
  540. init_data.comp_mode = comp_mode;
  541. init_data.p_comp_data = p_comp_addr;
  542. rc = qed_sp_init_request(p_hwfn, &p_ent,
  543. ISCSI_RAMROD_CMD_ID_CLEAR_SQ,
  544. PROTOCOLID_ISCSI, &init_data);
  545. if (rc)
  546. return rc;
  547. p_ramrod = &p_ent->ramrod.iscsi_empty;
  548. p_ramrod->op_code = ISCSI_RAMROD_CMD_ID_CLEAR_SQ;
  549. SET_FIELD(p_ramrod->flags,
  550. ISCSI_SLOW_PATH_HDR_LAYER_CODE, p_conn->layer_code);
  551. return qed_spq_post(p_hwfn, p_ent, NULL);
  552. }
  553. static int qed_sp_iscsi_func_stop(struct qed_hwfn *p_hwfn,
  554. enum spq_mode comp_mode,
  555. struct qed_spq_comp_cb *p_comp_addr)
  556. {
  557. struct iscsi_spe_func_dstry *p_ramrod = NULL;
  558. struct qed_spq_entry *p_ent = NULL;
  559. struct qed_sp_init_data init_data;
  560. int rc = 0;
  561. /* Get SPQ entry */
  562. memset(&init_data, 0, sizeof(init_data));
  563. init_data.cid = qed_spq_get_cid(p_hwfn);
  564. init_data.opaque_fid = p_hwfn->hw_info.opaque_fid;
  565. init_data.comp_mode = comp_mode;
  566. init_data.p_comp_data = p_comp_addr;
  567. rc = qed_sp_init_request(p_hwfn, &p_ent,
  568. ISCSI_RAMROD_CMD_ID_DESTROY_FUNC,
  569. PROTOCOLID_ISCSI, &init_data);
  570. if (rc)
  571. return rc;
  572. p_ramrod = &p_ent->ramrod.iscsi_destroy;
  573. p_ramrod->hdr.op_code = ISCSI_RAMROD_CMD_ID_DESTROY_FUNC;
  574. rc = qed_spq_post(p_hwfn, p_ent, NULL);
  575. qed_spq_unregister_async_cb(p_hwfn, PROTOCOLID_ISCSI);
  576. return rc;
  577. }
  578. static void __iomem *qed_iscsi_get_db_addr(struct qed_hwfn *p_hwfn, u32 cid)
  579. {
  580. return (u8 __iomem *)p_hwfn->doorbells +
  581. qed_db_addr(cid, DQ_DEMS_LEGACY);
  582. }
  583. static void __iomem *qed_iscsi_get_primary_bdq_prod(struct qed_hwfn *p_hwfn,
  584. u8 bdq_id)
  585. {
  586. if (RESC_NUM(p_hwfn, QED_BDQ)) {
  587. return (u8 __iomem *)p_hwfn->regview +
  588. GTT_BAR0_MAP_REG_MSDM_RAM +
  589. MSTORM_SCSI_BDQ_EXT_PROD_OFFSET(RESC_START(p_hwfn,
  590. QED_BDQ),
  591. bdq_id);
  592. } else {
  593. DP_NOTICE(p_hwfn, "BDQ is not allocated!\n");
  594. return NULL;
  595. }
  596. }
  597. static void __iomem *qed_iscsi_get_secondary_bdq_prod(struct qed_hwfn *p_hwfn,
  598. u8 bdq_id)
  599. {
  600. if (RESC_NUM(p_hwfn, QED_BDQ)) {
  601. return (u8 __iomem *)p_hwfn->regview +
  602. GTT_BAR0_MAP_REG_TSDM_RAM +
  603. TSTORM_SCSI_BDQ_EXT_PROD_OFFSET(RESC_START(p_hwfn,
  604. QED_BDQ),
  605. bdq_id);
  606. } else {
  607. DP_NOTICE(p_hwfn, "BDQ is not allocated!\n");
  608. return NULL;
  609. }
  610. }
  611. static int qed_iscsi_setup_connection(struct qed_hwfn *p_hwfn,
  612. struct qed_iscsi_conn *p_conn)
  613. {
  614. if (!p_conn->queue_cnts_virt_addr)
  615. goto nomem;
  616. memset(p_conn->queue_cnts_virt_addr, 0,
  617. sizeof(*p_conn->queue_cnts_virt_addr));
  618. if (!p_conn->tcp_upload_params_virt_addr)
  619. goto nomem;
  620. memset(p_conn->tcp_upload_params_virt_addr, 0,
  621. sizeof(*p_conn->tcp_upload_params_virt_addr));
  622. if (!p_conn->r2tq.p_virt_addr)
  623. goto nomem;
  624. qed_chain_pbl_zero_mem(&p_conn->r2tq);
  625. if (!p_conn->uhq.p_virt_addr)
  626. goto nomem;
  627. qed_chain_pbl_zero_mem(&p_conn->uhq);
  628. if (!p_conn->xhq.p_virt_addr)
  629. goto nomem;
  630. qed_chain_pbl_zero_mem(&p_conn->xhq);
  631. return 0;
  632. nomem:
  633. return -ENOMEM;
  634. }
  635. static int qed_iscsi_allocate_connection(struct qed_hwfn *p_hwfn,
  636. struct qed_iscsi_conn **p_out_conn)
  637. {
  638. u16 uhq_num_elements = 0, xhq_num_elements = 0, r2tq_num_elements = 0;
  639. struct scsi_terminate_extra_params *p_q_cnts = NULL;
  640. struct qed_iscsi_pf_params *p_params = NULL;
  641. struct tcp_upload_params *p_tcp = NULL;
  642. struct qed_iscsi_conn *p_conn = NULL;
  643. int rc = 0;
  644. /* Try finding a free connection that can be used */
  645. spin_lock_bh(&p_hwfn->p_iscsi_info->lock);
  646. if (!list_empty(&p_hwfn->p_iscsi_info->free_list))
  647. p_conn = list_first_entry(&p_hwfn->p_iscsi_info->free_list,
  648. struct qed_iscsi_conn, list_entry);
  649. if (p_conn) {
  650. list_del(&p_conn->list_entry);
  651. spin_unlock_bh(&p_hwfn->p_iscsi_info->lock);
  652. *p_out_conn = p_conn;
  653. return 0;
  654. }
  655. spin_unlock_bh(&p_hwfn->p_iscsi_info->lock);
  656. /* Need to allocate a new connection */
  657. p_params = &p_hwfn->pf_params.iscsi_pf_params;
  658. p_conn = kzalloc(sizeof(*p_conn), GFP_KERNEL);
  659. if (!p_conn)
  660. return -ENOMEM;
  661. p_q_cnts = dma_alloc_coherent(&p_hwfn->cdev->pdev->dev,
  662. sizeof(*p_q_cnts),
  663. &p_conn->queue_cnts_phys_addr,
  664. GFP_KERNEL);
  665. if (!p_q_cnts)
  666. goto nomem_queue_cnts_param;
  667. p_conn->queue_cnts_virt_addr = p_q_cnts;
  668. p_tcp = dma_alloc_coherent(&p_hwfn->cdev->pdev->dev,
  669. sizeof(*p_tcp),
  670. &p_conn->tcp_upload_params_phys_addr,
  671. GFP_KERNEL);
  672. if (!p_tcp)
  673. goto nomem_upload_param;
  674. p_conn->tcp_upload_params_virt_addr = p_tcp;
  675. r2tq_num_elements = p_params->num_r2tq_pages_in_ring *
  676. QED_CHAIN_PAGE_SIZE / 0x80;
  677. rc = qed_chain_alloc(p_hwfn->cdev,
  678. QED_CHAIN_USE_TO_CONSUME_PRODUCE,
  679. QED_CHAIN_MODE_PBL,
  680. QED_CHAIN_CNT_TYPE_U16,
  681. r2tq_num_elements, 0x80, &p_conn->r2tq, NULL);
  682. if (rc)
  683. goto nomem_r2tq;
  684. uhq_num_elements = p_params->num_uhq_pages_in_ring *
  685. QED_CHAIN_PAGE_SIZE / sizeof(struct iscsi_uhqe);
  686. rc = qed_chain_alloc(p_hwfn->cdev,
  687. QED_CHAIN_USE_TO_CONSUME_PRODUCE,
  688. QED_CHAIN_MODE_PBL,
  689. QED_CHAIN_CNT_TYPE_U16,
  690. uhq_num_elements,
  691. sizeof(struct iscsi_uhqe), &p_conn->uhq, NULL);
  692. if (rc)
  693. goto nomem_uhq;
  694. xhq_num_elements = uhq_num_elements;
  695. rc = qed_chain_alloc(p_hwfn->cdev,
  696. QED_CHAIN_USE_TO_CONSUME_PRODUCE,
  697. QED_CHAIN_MODE_PBL,
  698. QED_CHAIN_CNT_TYPE_U16,
  699. xhq_num_elements,
  700. sizeof(struct iscsi_xhqe), &p_conn->xhq, NULL);
  701. if (rc)
  702. goto nomem;
  703. p_conn->free_on_delete = true;
  704. *p_out_conn = p_conn;
  705. return 0;
  706. nomem:
  707. qed_chain_free(p_hwfn->cdev, &p_conn->uhq);
  708. nomem_uhq:
  709. qed_chain_free(p_hwfn->cdev, &p_conn->r2tq);
  710. nomem_r2tq:
  711. dma_free_coherent(&p_hwfn->cdev->pdev->dev,
  712. sizeof(struct tcp_upload_params),
  713. p_conn->tcp_upload_params_virt_addr,
  714. p_conn->tcp_upload_params_phys_addr);
  715. nomem_upload_param:
  716. dma_free_coherent(&p_hwfn->cdev->pdev->dev,
  717. sizeof(struct scsi_terminate_extra_params),
  718. p_conn->queue_cnts_virt_addr,
  719. p_conn->queue_cnts_phys_addr);
  720. nomem_queue_cnts_param:
  721. kfree(p_conn);
  722. return -ENOMEM;
  723. }
  724. static int qed_iscsi_acquire_connection(struct qed_hwfn *p_hwfn,
  725. struct qed_iscsi_conn *p_in_conn,
  726. struct qed_iscsi_conn **p_out_conn)
  727. {
  728. struct qed_iscsi_conn *p_conn = NULL;
  729. int rc = 0;
  730. u32 icid;
  731. spin_lock_bh(&p_hwfn->p_iscsi_info->lock);
  732. rc = qed_cxt_acquire_cid(p_hwfn, PROTOCOLID_ISCSI, &icid);
  733. spin_unlock_bh(&p_hwfn->p_iscsi_info->lock);
  734. if (rc)
  735. return rc;
  736. /* Use input connection or allocate a new one */
  737. if (p_in_conn)
  738. p_conn = p_in_conn;
  739. else
  740. rc = qed_iscsi_allocate_connection(p_hwfn, &p_conn);
  741. if (!rc)
  742. rc = qed_iscsi_setup_connection(p_hwfn, p_conn);
  743. if (rc) {
  744. spin_lock_bh(&p_hwfn->p_iscsi_info->lock);
  745. qed_cxt_release_cid(p_hwfn, icid);
  746. spin_unlock_bh(&p_hwfn->p_iscsi_info->lock);
  747. return rc;
  748. }
  749. p_conn->icid = icid;
  750. p_conn->conn_id = (u16)icid;
  751. p_conn->fw_cid = (p_hwfn->hw_info.opaque_fid << 16) | icid;
  752. *p_out_conn = p_conn;
  753. return rc;
  754. }
  755. static void qed_iscsi_release_connection(struct qed_hwfn *p_hwfn,
  756. struct qed_iscsi_conn *p_conn)
  757. {
  758. spin_lock_bh(&p_hwfn->p_iscsi_info->lock);
  759. list_add_tail(&p_conn->list_entry, &p_hwfn->p_iscsi_info->free_list);
  760. qed_cxt_release_cid(p_hwfn, p_conn->icid);
  761. spin_unlock_bh(&p_hwfn->p_iscsi_info->lock);
  762. }
  763. void qed_iscsi_free_connection(struct qed_hwfn *p_hwfn,
  764. struct qed_iscsi_conn *p_conn)
  765. {
  766. qed_chain_free(p_hwfn->cdev, &p_conn->xhq);
  767. qed_chain_free(p_hwfn->cdev, &p_conn->uhq);
  768. qed_chain_free(p_hwfn->cdev, &p_conn->r2tq);
  769. dma_free_coherent(&p_hwfn->cdev->pdev->dev,
  770. sizeof(struct tcp_upload_params),
  771. p_conn->tcp_upload_params_virt_addr,
  772. p_conn->tcp_upload_params_phys_addr);
  773. dma_free_coherent(&p_hwfn->cdev->pdev->dev,
  774. sizeof(struct scsi_terminate_extra_params),
  775. p_conn->queue_cnts_virt_addr,
  776. p_conn->queue_cnts_phys_addr);
  777. kfree(p_conn);
  778. }
  779. int qed_iscsi_alloc(struct qed_hwfn *p_hwfn)
  780. {
  781. struct qed_iscsi_info *p_iscsi_info;
  782. p_iscsi_info = kzalloc(sizeof(*p_iscsi_info), GFP_KERNEL);
  783. if (!p_iscsi_info)
  784. return -ENOMEM;
  785. INIT_LIST_HEAD(&p_iscsi_info->free_list);
  786. p_hwfn->p_iscsi_info = p_iscsi_info;
  787. return 0;
  788. }
  789. void qed_iscsi_setup(struct qed_hwfn *p_hwfn)
  790. {
  791. spin_lock_init(&p_hwfn->p_iscsi_info->lock);
  792. }
  793. void qed_iscsi_free(struct qed_hwfn *p_hwfn)
  794. {
  795. struct qed_iscsi_conn *p_conn = NULL;
  796. if (!p_hwfn->p_iscsi_info)
  797. return;
  798. while (!list_empty(&p_hwfn->p_iscsi_info->free_list)) {
  799. p_conn = list_first_entry(&p_hwfn->p_iscsi_info->free_list,
  800. struct qed_iscsi_conn, list_entry);
  801. if (p_conn) {
  802. list_del(&p_conn->list_entry);
  803. qed_iscsi_free_connection(p_hwfn, p_conn);
  804. }
  805. }
  806. kfree(p_hwfn->p_iscsi_info);
  807. p_hwfn->p_iscsi_info = NULL;
  808. }
  809. static void _qed_iscsi_get_tstats(struct qed_hwfn *p_hwfn,
  810. struct qed_ptt *p_ptt,
  811. struct qed_iscsi_stats *p_stats)
  812. {
  813. struct tstorm_iscsi_stats_drv tstats;
  814. u32 tstats_addr;
  815. memset(&tstats, 0, sizeof(tstats));
  816. tstats_addr = BAR0_MAP_REG_TSDM_RAM +
  817. TSTORM_ISCSI_RX_STATS_OFFSET(p_hwfn->rel_pf_id);
  818. qed_memcpy_from(p_hwfn, p_ptt, &tstats, tstats_addr, sizeof(tstats));
  819. p_stats->iscsi_rx_bytes_cnt =
  820. HILO_64_REGPAIR(tstats.iscsi_rx_bytes_cnt);
  821. p_stats->iscsi_rx_packet_cnt =
  822. HILO_64_REGPAIR(tstats.iscsi_rx_packet_cnt);
  823. p_stats->iscsi_rx_new_ooo_isle_events_cnt =
  824. HILO_64_REGPAIR(tstats.iscsi_rx_new_ooo_isle_events_cnt);
  825. p_stats->iscsi_cmdq_threshold_cnt =
  826. le32_to_cpu(tstats.iscsi_cmdq_threshold_cnt);
  827. p_stats->iscsi_rq_threshold_cnt =
  828. le32_to_cpu(tstats.iscsi_rq_threshold_cnt);
  829. p_stats->iscsi_immq_threshold_cnt =
  830. le32_to_cpu(tstats.iscsi_immq_threshold_cnt);
  831. }
  832. static void _qed_iscsi_get_mstats(struct qed_hwfn *p_hwfn,
  833. struct qed_ptt *p_ptt,
  834. struct qed_iscsi_stats *p_stats)
  835. {
  836. struct mstorm_iscsi_stats_drv mstats;
  837. u32 mstats_addr;
  838. memset(&mstats, 0, sizeof(mstats));
  839. mstats_addr = BAR0_MAP_REG_MSDM_RAM +
  840. MSTORM_ISCSI_RX_STATS_OFFSET(p_hwfn->rel_pf_id);
  841. qed_memcpy_from(p_hwfn, p_ptt, &mstats, mstats_addr, sizeof(mstats));
  842. p_stats->iscsi_rx_dropped_pdus_task_not_valid =
  843. HILO_64_REGPAIR(mstats.iscsi_rx_dropped_pdus_task_not_valid);
  844. }
  845. static void _qed_iscsi_get_ustats(struct qed_hwfn *p_hwfn,
  846. struct qed_ptt *p_ptt,
  847. struct qed_iscsi_stats *p_stats)
  848. {
  849. struct ustorm_iscsi_stats_drv ustats;
  850. u32 ustats_addr;
  851. memset(&ustats, 0, sizeof(ustats));
  852. ustats_addr = BAR0_MAP_REG_USDM_RAM +
  853. USTORM_ISCSI_RX_STATS_OFFSET(p_hwfn->rel_pf_id);
  854. qed_memcpy_from(p_hwfn, p_ptt, &ustats, ustats_addr, sizeof(ustats));
  855. p_stats->iscsi_rx_data_pdu_cnt =
  856. HILO_64_REGPAIR(ustats.iscsi_rx_data_pdu_cnt);
  857. p_stats->iscsi_rx_r2t_pdu_cnt =
  858. HILO_64_REGPAIR(ustats.iscsi_rx_r2t_pdu_cnt);
  859. p_stats->iscsi_rx_total_pdu_cnt =
  860. HILO_64_REGPAIR(ustats.iscsi_rx_total_pdu_cnt);
  861. }
  862. static void _qed_iscsi_get_xstats(struct qed_hwfn *p_hwfn,
  863. struct qed_ptt *p_ptt,
  864. struct qed_iscsi_stats *p_stats)
  865. {
  866. struct xstorm_iscsi_stats_drv xstats;
  867. u32 xstats_addr;
  868. memset(&xstats, 0, sizeof(xstats));
  869. xstats_addr = BAR0_MAP_REG_XSDM_RAM +
  870. XSTORM_ISCSI_TX_STATS_OFFSET(p_hwfn->rel_pf_id);
  871. qed_memcpy_from(p_hwfn, p_ptt, &xstats, xstats_addr, sizeof(xstats));
  872. p_stats->iscsi_tx_go_to_slow_start_event_cnt =
  873. HILO_64_REGPAIR(xstats.iscsi_tx_go_to_slow_start_event_cnt);
  874. p_stats->iscsi_tx_fast_retransmit_event_cnt =
  875. HILO_64_REGPAIR(xstats.iscsi_tx_fast_retransmit_event_cnt);
  876. }
  877. static void _qed_iscsi_get_ystats(struct qed_hwfn *p_hwfn,
  878. struct qed_ptt *p_ptt,
  879. struct qed_iscsi_stats *p_stats)
  880. {
  881. struct ystorm_iscsi_stats_drv ystats;
  882. u32 ystats_addr;
  883. memset(&ystats, 0, sizeof(ystats));
  884. ystats_addr = BAR0_MAP_REG_YSDM_RAM +
  885. YSTORM_ISCSI_TX_STATS_OFFSET(p_hwfn->rel_pf_id);
  886. qed_memcpy_from(p_hwfn, p_ptt, &ystats, ystats_addr, sizeof(ystats));
  887. p_stats->iscsi_tx_data_pdu_cnt =
  888. HILO_64_REGPAIR(ystats.iscsi_tx_data_pdu_cnt);
  889. p_stats->iscsi_tx_r2t_pdu_cnt =
  890. HILO_64_REGPAIR(ystats.iscsi_tx_r2t_pdu_cnt);
  891. p_stats->iscsi_tx_total_pdu_cnt =
  892. HILO_64_REGPAIR(ystats.iscsi_tx_total_pdu_cnt);
  893. }
  894. static void _qed_iscsi_get_pstats(struct qed_hwfn *p_hwfn,
  895. struct qed_ptt *p_ptt,
  896. struct qed_iscsi_stats *p_stats)
  897. {
  898. struct pstorm_iscsi_stats_drv pstats;
  899. u32 pstats_addr;
  900. memset(&pstats, 0, sizeof(pstats));
  901. pstats_addr = BAR0_MAP_REG_PSDM_RAM +
  902. PSTORM_ISCSI_TX_STATS_OFFSET(p_hwfn->rel_pf_id);
  903. qed_memcpy_from(p_hwfn, p_ptt, &pstats, pstats_addr, sizeof(pstats));
  904. p_stats->iscsi_tx_bytes_cnt =
  905. HILO_64_REGPAIR(pstats.iscsi_tx_bytes_cnt);
  906. p_stats->iscsi_tx_packet_cnt =
  907. HILO_64_REGPAIR(pstats.iscsi_tx_packet_cnt);
  908. }
  909. static int qed_iscsi_get_stats(struct qed_hwfn *p_hwfn,
  910. struct qed_iscsi_stats *stats)
  911. {
  912. struct qed_ptt *p_ptt;
  913. memset(stats, 0, sizeof(*stats));
  914. p_ptt = qed_ptt_acquire(p_hwfn);
  915. if (!p_ptt) {
  916. DP_ERR(p_hwfn, "Failed to acquire ptt\n");
  917. return -EAGAIN;
  918. }
  919. _qed_iscsi_get_tstats(p_hwfn, p_ptt, stats);
  920. _qed_iscsi_get_mstats(p_hwfn, p_ptt, stats);
  921. _qed_iscsi_get_ustats(p_hwfn, p_ptt, stats);
  922. _qed_iscsi_get_xstats(p_hwfn, p_ptt, stats);
  923. _qed_iscsi_get_ystats(p_hwfn, p_ptt, stats);
  924. _qed_iscsi_get_pstats(p_hwfn, p_ptt, stats);
  925. qed_ptt_release(p_hwfn, p_ptt);
  926. return 0;
  927. }
  928. struct qed_hash_iscsi_con {
  929. struct hlist_node node;
  930. struct qed_iscsi_conn *con;
  931. };
  932. static int qed_fill_iscsi_dev_info(struct qed_dev *cdev,
  933. struct qed_dev_iscsi_info *info)
  934. {
  935. struct qed_hwfn *hwfn = QED_LEADING_HWFN(cdev);
  936. int rc;
  937. memset(info, 0, sizeof(*info));
  938. rc = qed_fill_dev_info(cdev, &info->common);
  939. info->primary_dbq_rq_addr =
  940. qed_iscsi_get_primary_bdq_prod(hwfn, BDQ_ID_RQ);
  941. info->secondary_bdq_rq_addr =
  942. qed_iscsi_get_secondary_bdq_prod(hwfn, BDQ_ID_RQ);
  943. info->num_cqs = FEAT_NUM(hwfn, QED_ISCSI_CQ);
  944. return rc;
  945. }
  946. static void qed_register_iscsi_ops(struct qed_dev *cdev,
  947. struct qed_iscsi_cb_ops *ops, void *cookie)
  948. {
  949. cdev->protocol_ops.iscsi = ops;
  950. cdev->ops_cookie = cookie;
  951. }
  952. static struct qed_hash_iscsi_con *qed_iscsi_get_hash(struct qed_dev *cdev,
  953. u32 handle)
  954. {
  955. struct qed_hash_iscsi_con *hash_con = NULL;
  956. if (!(cdev->flags & QED_FLAG_STORAGE_STARTED))
  957. return NULL;
  958. hash_for_each_possible(cdev->connections, hash_con, node, handle) {
  959. if (hash_con->con->icid == handle)
  960. break;
  961. }
  962. if (!hash_con || (hash_con->con->icid != handle))
  963. return NULL;
  964. return hash_con;
  965. }
  966. static int qed_iscsi_stop(struct qed_dev *cdev)
  967. {
  968. int rc;
  969. if (!(cdev->flags & QED_FLAG_STORAGE_STARTED)) {
  970. DP_NOTICE(cdev, "iscsi already stopped\n");
  971. return 0;
  972. }
  973. if (!hash_empty(cdev->connections)) {
  974. DP_NOTICE(cdev,
  975. "Can't stop iscsi - not all connections were returned\n");
  976. return -EINVAL;
  977. }
  978. /* Stop the iscsi */
  979. rc = qed_sp_iscsi_func_stop(QED_LEADING_HWFN(cdev),
  980. QED_SPQ_MODE_EBLOCK, NULL);
  981. cdev->flags &= ~QED_FLAG_STORAGE_STARTED;
  982. return rc;
  983. }
  984. static int qed_iscsi_start(struct qed_dev *cdev,
  985. struct qed_iscsi_tid *tasks,
  986. void *event_context,
  987. iscsi_event_cb_t async_event_cb)
  988. {
  989. int rc;
  990. struct qed_tid_mem *tid_info;
  991. if (cdev->flags & QED_FLAG_STORAGE_STARTED) {
  992. DP_NOTICE(cdev, "iscsi already started;\n");
  993. return 0;
  994. }
  995. rc = qed_sp_iscsi_func_start(QED_LEADING_HWFN(cdev),
  996. QED_SPQ_MODE_EBLOCK, NULL, event_context,
  997. async_event_cb);
  998. if (rc) {
  999. DP_NOTICE(cdev, "Failed to start iscsi\n");
  1000. return rc;
  1001. }
  1002. cdev->flags |= QED_FLAG_STORAGE_STARTED;
  1003. hash_init(cdev->connections);
  1004. if (!tasks)
  1005. return 0;
  1006. tid_info = kzalloc(sizeof(*tid_info), GFP_KERNEL);
  1007. if (!tid_info) {
  1008. qed_iscsi_stop(cdev);
  1009. return -ENOMEM;
  1010. }
  1011. rc = qed_cxt_get_tid_mem_info(QED_LEADING_HWFN(cdev),
  1012. tid_info);
  1013. if (rc) {
  1014. DP_NOTICE(cdev, "Failed to gather task information\n");
  1015. qed_iscsi_stop(cdev);
  1016. kfree(tid_info);
  1017. return rc;
  1018. }
  1019. /* Fill task information */
  1020. tasks->size = tid_info->tid_size;
  1021. tasks->num_tids_per_block = tid_info->num_tids_per_block;
  1022. memcpy(tasks->blocks, tid_info->blocks,
  1023. MAX_TID_BLOCKS_ISCSI * sizeof(u8 *));
  1024. kfree(tid_info);
  1025. return 0;
  1026. }
  1027. static int qed_iscsi_acquire_conn(struct qed_dev *cdev,
  1028. u32 *handle,
  1029. u32 *fw_cid, void __iomem **p_doorbell)
  1030. {
  1031. struct qed_hash_iscsi_con *hash_con;
  1032. int rc;
  1033. /* Allocate a hashed connection */
  1034. hash_con = kzalloc(sizeof(*hash_con), GFP_ATOMIC);
  1035. if (!hash_con)
  1036. return -ENOMEM;
  1037. /* Acquire the connection */
  1038. rc = qed_iscsi_acquire_connection(QED_LEADING_HWFN(cdev), NULL,
  1039. &hash_con->con);
  1040. if (rc) {
  1041. DP_NOTICE(cdev, "Failed to acquire Connection\n");
  1042. kfree(hash_con);
  1043. return rc;
  1044. }
  1045. /* Added the connection to hash table */
  1046. *handle = hash_con->con->icid;
  1047. *fw_cid = hash_con->con->fw_cid;
  1048. hash_add(cdev->connections, &hash_con->node, *handle);
  1049. if (p_doorbell)
  1050. *p_doorbell = qed_iscsi_get_db_addr(QED_LEADING_HWFN(cdev),
  1051. *handle);
  1052. return 0;
  1053. }
  1054. static int qed_iscsi_release_conn(struct qed_dev *cdev, u32 handle)
  1055. {
  1056. struct qed_hash_iscsi_con *hash_con;
  1057. hash_con = qed_iscsi_get_hash(cdev, handle);
  1058. if (!hash_con) {
  1059. DP_NOTICE(cdev, "Failed to find connection for handle %d\n",
  1060. handle);
  1061. return -EINVAL;
  1062. }
  1063. hlist_del(&hash_con->node);
  1064. qed_iscsi_release_connection(QED_LEADING_HWFN(cdev), hash_con->con);
  1065. kfree(hash_con);
  1066. return 0;
  1067. }
  1068. static int qed_iscsi_offload_conn(struct qed_dev *cdev,
  1069. u32 handle,
  1070. struct qed_iscsi_params_offload *conn_info)
  1071. {
  1072. struct qed_hash_iscsi_con *hash_con;
  1073. struct qed_iscsi_conn *con;
  1074. hash_con = qed_iscsi_get_hash(cdev, handle);
  1075. if (!hash_con) {
  1076. DP_NOTICE(cdev, "Failed to find connection for handle %d\n",
  1077. handle);
  1078. return -EINVAL;
  1079. }
  1080. /* Update the connection with information from the params */
  1081. con = hash_con->con;
  1082. ether_addr_copy(con->local_mac, conn_info->src.mac);
  1083. ether_addr_copy(con->remote_mac, conn_info->dst.mac);
  1084. memcpy(con->local_ip, conn_info->src.ip, sizeof(con->local_ip));
  1085. memcpy(con->remote_ip, conn_info->dst.ip, sizeof(con->remote_ip));
  1086. con->local_port = conn_info->src.port;
  1087. con->remote_port = conn_info->dst.port;
  1088. con->layer_code = conn_info->layer_code;
  1089. con->sq_pbl_addr = conn_info->sq_pbl_addr;
  1090. con->initial_ack = conn_info->initial_ack;
  1091. con->vlan_id = conn_info->vlan_id;
  1092. con->tcp_flags = conn_info->tcp_flags;
  1093. con->ip_version = conn_info->ip_version;
  1094. con->default_cq = conn_info->default_cq;
  1095. con->ka_max_probe_cnt = conn_info->ka_max_probe_cnt;
  1096. con->dup_ack_theshold = conn_info->dup_ack_theshold;
  1097. con->rcv_next = conn_info->rcv_next;
  1098. con->snd_una = conn_info->snd_una;
  1099. con->snd_next = conn_info->snd_next;
  1100. con->snd_max = conn_info->snd_max;
  1101. con->snd_wnd = conn_info->snd_wnd;
  1102. con->rcv_wnd = conn_info->rcv_wnd;
  1103. con->snd_wl1 = conn_info->snd_wl1;
  1104. con->cwnd = conn_info->cwnd;
  1105. con->ss_thresh = conn_info->ss_thresh;
  1106. con->srtt = conn_info->srtt;
  1107. con->rtt_var = conn_info->rtt_var;
  1108. con->ts_time = conn_info->ts_time;
  1109. con->ts_recent = conn_info->ts_recent;
  1110. con->ts_recent_age = conn_info->ts_recent_age;
  1111. con->total_rt = conn_info->total_rt;
  1112. con->ka_timeout_delta = conn_info->ka_timeout_delta;
  1113. con->rt_timeout_delta = conn_info->rt_timeout_delta;
  1114. con->dup_ack_cnt = conn_info->dup_ack_cnt;
  1115. con->snd_wnd_probe_cnt = conn_info->snd_wnd_probe_cnt;
  1116. con->ka_probe_cnt = conn_info->ka_probe_cnt;
  1117. con->rt_cnt = conn_info->rt_cnt;
  1118. con->flow_label = conn_info->flow_label;
  1119. con->ka_timeout = conn_info->ka_timeout;
  1120. con->ka_interval = conn_info->ka_interval;
  1121. con->max_rt_time = conn_info->max_rt_time;
  1122. con->initial_rcv_wnd = conn_info->initial_rcv_wnd;
  1123. con->ttl = conn_info->ttl;
  1124. con->tos_or_tc = conn_info->tos_or_tc;
  1125. con->remote_port = conn_info->remote_port;
  1126. con->local_port = conn_info->local_port;
  1127. con->mss = conn_info->mss;
  1128. con->snd_wnd_scale = conn_info->snd_wnd_scale;
  1129. con->rcv_wnd_scale = conn_info->rcv_wnd_scale;
  1130. con->ts_ticks_per_second = conn_info->ts_ticks_per_second;
  1131. con->da_timeout_value = conn_info->da_timeout_value;
  1132. con->ack_frequency = conn_info->ack_frequency;
  1133. /* Set default values on other connection fields */
  1134. con->offl_flags = 0x1;
  1135. return qed_sp_iscsi_conn_offload(QED_LEADING_HWFN(cdev), con,
  1136. QED_SPQ_MODE_EBLOCK, NULL);
  1137. }
  1138. static int qed_iscsi_update_conn(struct qed_dev *cdev,
  1139. u32 handle,
  1140. struct qed_iscsi_params_update *conn_info)
  1141. {
  1142. struct qed_hash_iscsi_con *hash_con;
  1143. struct qed_iscsi_conn *con;
  1144. hash_con = qed_iscsi_get_hash(cdev, handle);
  1145. if (!hash_con) {
  1146. DP_NOTICE(cdev, "Failed to find connection for handle %d\n",
  1147. handle);
  1148. return -EINVAL;
  1149. }
  1150. /* Update the connection with information from the params */
  1151. con = hash_con->con;
  1152. con->update_flag = conn_info->update_flag;
  1153. con->max_seq_size = conn_info->max_seq_size;
  1154. con->max_recv_pdu_length = conn_info->max_recv_pdu_length;
  1155. con->max_send_pdu_length = conn_info->max_send_pdu_length;
  1156. con->first_seq_length = conn_info->first_seq_length;
  1157. con->exp_stat_sn = conn_info->exp_stat_sn;
  1158. return qed_sp_iscsi_conn_update(QED_LEADING_HWFN(cdev), con,
  1159. QED_SPQ_MODE_EBLOCK, NULL);
  1160. }
  1161. static int qed_iscsi_clear_conn_sq(struct qed_dev *cdev, u32 handle)
  1162. {
  1163. struct qed_hash_iscsi_con *hash_con;
  1164. hash_con = qed_iscsi_get_hash(cdev, handle);
  1165. if (!hash_con) {
  1166. DP_NOTICE(cdev, "Failed to find connection for handle %d\n",
  1167. handle);
  1168. return -EINVAL;
  1169. }
  1170. return qed_sp_iscsi_conn_clear_sq(QED_LEADING_HWFN(cdev),
  1171. hash_con->con,
  1172. QED_SPQ_MODE_EBLOCK, NULL);
  1173. }
  1174. static int qed_iscsi_destroy_conn(struct qed_dev *cdev,
  1175. u32 handle, u8 abrt_conn)
  1176. {
  1177. struct qed_hash_iscsi_con *hash_con;
  1178. hash_con = qed_iscsi_get_hash(cdev, handle);
  1179. if (!hash_con) {
  1180. DP_NOTICE(cdev, "Failed to find connection for handle %d\n",
  1181. handle);
  1182. return -EINVAL;
  1183. }
  1184. hash_con->con->abortive_dsconnect = abrt_conn;
  1185. return qed_sp_iscsi_conn_terminate(QED_LEADING_HWFN(cdev),
  1186. hash_con->con,
  1187. QED_SPQ_MODE_EBLOCK, NULL);
  1188. }
  1189. static int qed_iscsi_stats(struct qed_dev *cdev, struct qed_iscsi_stats *stats)
  1190. {
  1191. return qed_iscsi_get_stats(QED_LEADING_HWFN(cdev), stats);
  1192. }
  1193. static int qed_iscsi_change_mac(struct qed_dev *cdev,
  1194. u32 handle, const u8 *mac)
  1195. {
  1196. struct qed_hash_iscsi_con *hash_con;
  1197. hash_con = qed_iscsi_get_hash(cdev, handle);
  1198. if (!hash_con) {
  1199. DP_NOTICE(cdev, "Failed to find connection for handle %d\n",
  1200. handle);
  1201. return -EINVAL;
  1202. }
  1203. return qed_sp_iscsi_mac_update(QED_LEADING_HWFN(cdev),
  1204. hash_con->con,
  1205. QED_SPQ_MODE_EBLOCK, NULL);
  1206. }
  1207. void qed_get_protocol_stats_iscsi(struct qed_dev *cdev,
  1208. struct qed_mcp_iscsi_stats *stats)
  1209. {
  1210. struct qed_iscsi_stats proto_stats;
  1211. /* Retrieve FW statistics */
  1212. memset(&proto_stats, 0, sizeof(proto_stats));
  1213. if (qed_iscsi_stats(cdev, &proto_stats)) {
  1214. DP_VERBOSE(cdev, QED_MSG_STORAGE,
  1215. "Failed to collect ISCSI statistics\n");
  1216. return;
  1217. }
  1218. /* Translate FW statistics into struct */
  1219. stats->rx_pdus = proto_stats.iscsi_rx_total_pdu_cnt;
  1220. stats->tx_pdus = proto_stats.iscsi_tx_total_pdu_cnt;
  1221. stats->rx_bytes = proto_stats.iscsi_rx_bytes_cnt;
  1222. stats->tx_bytes = proto_stats.iscsi_tx_bytes_cnt;
  1223. }
  1224. static const struct qed_iscsi_ops qed_iscsi_ops_pass = {
  1225. .common = &qed_common_ops_pass,
  1226. .ll2 = &qed_ll2_ops_pass,
  1227. .fill_dev_info = &qed_fill_iscsi_dev_info,
  1228. .register_ops = &qed_register_iscsi_ops,
  1229. .start = &qed_iscsi_start,
  1230. .stop = &qed_iscsi_stop,
  1231. .acquire_conn = &qed_iscsi_acquire_conn,
  1232. .release_conn = &qed_iscsi_release_conn,
  1233. .offload_conn = &qed_iscsi_offload_conn,
  1234. .update_conn = &qed_iscsi_update_conn,
  1235. .destroy_conn = &qed_iscsi_destroy_conn,
  1236. .clear_sq = &qed_iscsi_clear_conn_sq,
  1237. .get_stats = &qed_iscsi_stats,
  1238. .change_mac = &qed_iscsi_change_mac,
  1239. };
  1240. const struct qed_iscsi_ops *qed_get_iscsi_ops(void)
  1241. {
  1242. return &qed_iscsi_ops_pass;
  1243. }
  1244. EXPORT_SYMBOL(qed_get_iscsi_ops);
  1245. void qed_put_iscsi_ops(void)
  1246. {
  1247. }
  1248. EXPORT_SYMBOL(qed_put_iscsi_ops);