^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Copyright 2014 Cisco Systems, Inc. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * This program is free software; you may redistribute it and/or modify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * it under the terms of the GNU General Public License as published by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * the Free Software Foundation; version 2 of the License.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * SOFTWARE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/workqueue.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/mempool.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <scsi/scsi_tcq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include "snic_io.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include "snic.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include "cq_enet_desc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include "snic_fwint.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * snic_handle_link : Handles link flaps.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) snic_handle_link(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) struct snic *snic = container_of(work, struct snic, link_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) if (snic->config.xpt_type == SNIC_DAS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) snic->link_status = svnic_dev_link_status(snic->vdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) snic->link_down_cnt = svnic_dev_link_down_cnt(snic->vdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) SNIC_HOST_INFO(snic->shost, "Link Event: Link %s.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) ((snic->link_status) ? "Up" : "Down"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) SNIC_ASSERT_NOT_IMPL(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * snic_ver_enc : Encodes version str to int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * version string is similar to netmask string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) snic_ver_enc(const char *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) int v[4] = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) int i = 0, x = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) char c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) const char *p = s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /* validate version string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) if ((strlen(s) > 15) || (strlen(s) < 7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) while ((c = *p++)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) if (c == '.') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) if (i > 3 || !isdigit(c))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) v[i] = v[i] * 10 + (c - '0');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) /* validate sub version numbers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) for (i = 3; i >= 0; i--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) if (v[i] > 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) x |= (v[0] << 24) | v[1] << 16 | v[2] << 8 | v[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (x == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) SNIC_ERR("Invalid version string [%s].\n", s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) return x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) } /* end of snic_ver_enc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * snic_qeueue_exch_ver_req :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * Queues Exchange Version Request, to communicate host information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * in return, it gets firmware version details
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) snic_queue_exch_ver_req(struct snic *snic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) struct snic_req_info *rqi = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) struct snic_host_req *req = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) u32 ver = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) SNIC_HOST_INFO(snic->shost, "Exch Ver Req Preparing...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) rqi = snic_req_init(snic, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) if (!rqi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) SNIC_HOST_ERR(snic->shost,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) "Queuing Exch Ver Req failed, err = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) req = rqi_to_req(rqi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) /* Initialize snic_host_req */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) snic_io_hdr_enc(&req->hdr, SNIC_REQ_EXCH_VER, 0, SCSI_NO_TAG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) snic->config.hid, 0, (ulong)rqi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) ver = snic_ver_enc(SNIC_DRV_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) req->u.exch_ver.drvr_ver = cpu_to_le32(ver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) req->u.exch_ver.os_type = cpu_to_le32(SNIC_OS_LINUX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) snic_handle_untagged_req(snic, rqi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) ret = snic_queue_wq_desc(snic, req, sizeof(*req));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) snic_release_untagged_req(snic, rqi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) SNIC_HOST_ERR(snic->shost,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) "Queuing Exch Ver Req failed, err = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) SNIC_HOST_INFO(snic->shost, "Exch Ver Req is issued. ret = %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) } /* end of snic_queue_exch_ver_req */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * snic_io_exch_ver_cmpl_handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) snic_io_exch_ver_cmpl_handler(struct snic *snic, struct snic_fw_req *fwreq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) struct snic_req_info *rqi = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) struct snic_exch_ver_rsp *exv_cmpl = &fwreq->u.exch_ver_cmpl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) u8 typ, hdr_stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) u32 cmnd_id, hid, max_sgs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) ulong ctx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) SNIC_HOST_INFO(snic->shost, "Exch Ver Compl Received.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) snic_io_hdr_dec(&fwreq->hdr, &typ, &hdr_stat, &cmnd_id, &hid, &ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) SNIC_BUG_ON(snic->config.hid != hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) rqi = (struct snic_req_info *) ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if (hdr_stat) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) SNIC_HOST_ERR(snic->shost,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) "Exch Ver Completed w/ err status %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) hdr_stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) goto exch_cmpl_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) spin_lock_irqsave(&snic->snic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) snic->fwinfo.fw_ver = le32_to_cpu(exv_cmpl->version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) snic->fwinfo.hid = le32_to_cpu(exv_cmpl->hid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) snic->fwinfo.max_concur_ios = le32_to_cpu(exv_cmpl->max_concur_ios);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) snic->fwinfo.max_sgs_per_cmd = le32_to_cpu(exv_cmpl->max_sgs_per_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) snic->fwinfo.max_io_sz = le32_to_cpu(exv_cmpl->max_io_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) snic->fwinfo.max_tgts = le32_to_cpu(exv_cmpl->max_tgts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) snic->fwinfo.io_tmo = le16_to_cpu(exv_cmpl->io_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) SNIC_HOST_INFO(snic->shost,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) "vers %u hid %u max_concur_ios %u max_sgs_per_cmd %u max_io_sz %u max_tgts %u fw tmo %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) snic->fwinfo.fw_ver,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) snic->fwinfo.hid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) snic->fwinfo.max_concur_ios,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) snic->fwinfo.max_sgs_per_cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) snic->fwinfo.max_io_sz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) snic->fwinfo.max_tgts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) snic->fwinfo.io_tmo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) SNIC_HOST_INFO(snic->shost,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) "HBA Capabilities = 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) le32_to_cpu(exv_cmpl->hba_cap));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) /* Updating SGList size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) max_sgs = snic->fwinfo.max_sgs_per_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if (max_sgs && max_sgs < SNIC_MAX_SG_DESC_CNT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) snic->shost->sg_tablesize = max_sgs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) SNIC_HOST_INFO(snic->shost, "Max SGs set to %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) snic->shost->sg_tablesize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) } else if (max_sgs > snic->shost->sg_tablesize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) SNIC_HOST_INFO(snic->shost,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) "Target type %d Supports Larger Max SGList %d than driver's Max SG List %d.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) snic->config.xpt_type, max_sgs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) snic->shost->sg_tablesize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if (snic->shost->can_queue > snic->fwinfo.max_concur_ios)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) snic->shost->can_queue = snic->fwinfo.max_concur_ios;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) snic->shost->max_sectors = snic->fwinfo.max_io_sz >> 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (snic->fwinfo.wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) complete(snic->fwinfo.wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) spin_unlock_irqrestore(&snic->snic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) exch_cmpl_end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) snic_release_untagged_req(snic, rqi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) SNIC_HOST_INFO(snic->shost, "Exch_cmpl Done, hdr_stat %d.\n", hdr_stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) } /* end of snic_io_exch_ver_cmpl_handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) * snic_get_conf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * Synchronous call, and Retrieves snic params.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) snic_get_conf(struct snic *snic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) DECLARE_COMPLETION_ONSTACK(wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) int nr_retries = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) SNIC_HOST_INFO(snic->shost, "Retrieving snic params.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) spin_lock_irqsave(&snic->snic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) memset(&snic->fwinfo, 0, sizeof(snic->fwinfo));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) snic->fwinfo.wait = &wait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) spin_unlock_irqrestore(&snic->snic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) /* Additional delay to handle HW Resource initialization. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) msleep(50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) * Exch ver req can be ignored by FW, if HW Resource initialization
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) * is in progress, Hence retry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) ret = snic_queue_exch_ver_req(snic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) wait_for_completion_timeout(&wait, msecs_to_jiffies(2000));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) spin_lock_irqsave(&snic->snic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) ret = (snic->fwinfo.fw_ver != 0) ? 0 : -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) SNIC_HOST_ERR(snic->shost,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) "Failed to retrieve snic params,\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) /* Unset fwinfo.wait, on success or on last retry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (ret == 0 || nr_retries == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) snic->fwinfo.wait = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) spin_unlock_irqrestore(&snic->snic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) } while (ret && --nr_retries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) } /* end of snic_get_info */