aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qedi/qedi_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/qedi/qedi_main.c')
-rw-r--r--drivers/scsi/qedi/qedi_main.c87
1 files changed, 64 insertions, 23 deletions
diff --git a/drivers/scsi/qedi/qedi_main.c b/drivers/scsi/qedi/qedi_main.c
index 311eb22068e1..5c53409a8cea 100644
--- a/drivers/scsi/qedi/qedi_main.c
+++ b/drivers/scsi/qedi/qedi_main.c
@@ -44,6 +44,11 @@ module_param(qedi_io_tracing, uint, 0644);
MODULE_PARM_DESC(qedi_io_tracing,
" Enable logging of SCSI requests/completions into trace buffer. (default off).");
+uint qedi_ll2_buf_size = 0x400;
+module_param(qedi_ll2_buf_size, uint, 0644);
+MODULE_PARM_DESC(qedi_ll2_buf_size,
+ "parameter to set ping packet size, default - 0x400, Jumbo packets - 0x2400.");
+
const struct qed_iscsi_ops *qedi_ops;
static struct scsi_transport_template *qedi_scsi_transport;
static struct pci_driver qedi_pci_driver;
@@ -228,7 +233,7 @@ static int __qedi_alloc_uio_rings(struct qedi_uio_dev *udev)
}
/* Allocating memory for Tx/Rx pkt buffer */
- udev->ll2_buf_size = TX_RX_RING * LL2_SINGLE_BUF_SIZE;
+ udev->ll2_buf_size = TX_RX_RING * qedi_ll2_buf_size;
udev->ll2_buf_size = QEDI_PAGE_ALIGN(udev->ll2_buf_size);
udev->ll2_buf = (void *)__get_free_pages(GFP_KERNEL | __GFP_COMP |
__GFP_ZERO, 2);
@@ -283,7 +288,7 @@ static int qedi_alloc_uio_rings(struct qedi_ctx *qedi)
qedi->udev = udev;
udev->tx_pkt = udev->ll2_buf;
- udev->rx_pkt = udev->ll2_buf + LL2_SINGLE_BUF_SIZE;
+ udev->rx_pkt = udev->ll2_buf + qedi_ll2_buf_size;
return 0;
err_uctrl:
@@ -658,7 +663,7 @@ static int qedi_ll2_rx(void *cookie, struct sk_buff *skb, u32 arg1, u32 arg2)
struct qedi_uio_dev *udev;
struct qedi_uio_ctrl *uctrl;
struct skb_work_list *work;
- u32 prod;
+ struct ethhdr *eh;
if (!qedi) {
QEDI_ERR(NULL, "qedi is NULL\n");
@@ -672,6 +677,29 @@ static int qedi_ll2_rx(void *cookie, struct sk_buff *skb, u32 arg1, u32 arg2)
return 0;
}
+ eh = (struct ethhdr *)skb->data;
+ /* Undo VLAN encapsulation */
+ if (eh->h_proto == htons(ETH_P_8021Q)) {
+ memmove((u8 *)eh + VLAN_HLEN, eh, ETH_ALEN * 2);
+ eh = (struct ethhdr *)skb_pull(skb, VLAN_HLEN);
+ skb_reset_mac_header(skb);
+ }
+
+ /* Filter out non FIP/FCoE frames here to free them faster */
+ if (eh->h_proto != htons(ETH_P_ARP) &&
+ eh->h_proto != htons(ETH_P_IP) &&
+ eh->h_proto != htons(ETH_P_IPV6)) {
+ QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_LL2,
+ "Dropping frame ethertype [0x%x] len [0x%x].\n",
+ eh->h_proto, skb->len);
+ kfree_skb(skb);
+ return 0;
+ }
+
+ QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_LL2,
+ "Allowed frame ethertype [0x%x] len [0x%x].\n",
+ eh->h_proto, skb->len);
+
udev = qedi->udev;
uctrl = udev->uctrl;
@@ -694,17 +722,10 @@ static int qedi_ll2_rx(void *cookie, struct sk_buff *skb, u32 arg1, u32 arg2)
spin_lock_bh(&qedi->ll2_lock);
list_add_tail(&work->list, &qedi->ll2_skb_list);
+ spin_unlock_bh(&qedi->ll2_lock);
- ++uctrl->hw_rx_prod_cnt;
- prod = (uctrl->hw_rx_prod + 1) % RX_RING;
- if (prod != uctrl->host_rx_cons) {
- uctrl->hw_rx_prod = prod;
- spin_unlock_bh(&qedi->ll2_lock);
- wake_up_process(qedi->ll2_recv_thread);
- return 0;
- }
+ wake_up_process(qedi->ll2_recv_thread);
- spin_unlock_bh(&qedi->ll2_lock);
return 0;
}
@@ -719,6 +740,7 @@ static int qedi_ll2_process_skb(struct qedi_ctx *qedi, struct sk_buff *skb,
u32 rx_bd_prod;
void *pkt;
int len = 0;
+ u32 prod;
if (!qedi) {
QEDI_ERR(NULL, "qedi is NULL\n");
@@ -727,12 +749,16 @@ static int qedi_ll2_process_skb(struct qedi_ctx *qedi, struct sk_buff *skb,
udev = qedi->udev;
uctrl = udev->uctrl;
- pkt = udev->rx_pkt + (uctrl->hw_rx_prod * LL2_SINGLE_BUF_SIZE);
- len = min_t(u32, skb->len, (u32)LL2_SINGLE_BUF_SIZE);
+
+ ++uctrl->hw_rx_prod_cnt;
+ prod = (uctrl->hw_rx_prod + 1) % RX_RING;
+
+ pkt = udev->rx_pkt + (prod * qedi_ll2_buf_size);
+ len = min_t(u32, skb->len, (u32)qedi_ll2_buf_size);
memcpy(pkt, skb->data, len);
memset(&rxbd, 0, sizeof(rxbd));
- rxbd.rx_pkt_index = uctrl->hw_rx_prod;
+ rxbd.rx_pkt_index = prod;
rxbd.rx_pkt_len = len;
rxbd.vlan_id = vlan_id;
@@ -743,6 +769,16 @@ static int qedi_ll2_process_skb(struct qedi_ctx *qedi, struct sk_buff *skb,
memcpy(p_rxbd, &rxbd, sizeof(rxbd));
+ QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_LL2,
+ "hw_rx_prod [%d] prod [%d] hw_rx_bd_prod [%d] rx_pkt_idx [%d] rx_len [%d].\n",
+ uctrl->hw_rx_prod, prod, uctrl->hw_rx_bd_prod,
+ rxbd.rx_pkt_index, rxbd.rx_pkt_len);
+ QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_LL2,
+ "host_rx_cons [%d] hw_rx_bd_cons [%d].\n",
+ uctrl->host_rx_cons, uctrl->host_rx_bd_cons);
+
+ uctrl->hw_rx_prod = prod;
+
/* notify the iscsiuio about new packet */
uio_event_notify(&udev->qedi_uinfo);
@@ -795,7 +831,7 @@ static int qedi_set_iscsi_pf_param(struct qedi_ctx *qedi)
int rval = 0;
- num_sq_pages = (MAX_OUSTANDING_TASKS_PER_CON * 8) / PAGE_SIZE;
+ num_sq_pages = (MAX_OUTSTANDING_TASKS_PER_CON * 8) / QEDI_PAGE_SIZE;
qedi->num_queues = MIN_NUM_CPUS_MSIX(qedi);
@@ -833,7 +869,7 @@ static int qedi_set_iscsi_pf_param(struct qedi_ctx *qedi)
qedi->pf_params.iscsi_pf_params.max_fin_rt = 2;
for (log_page_size = 0 ; log_page_size < 32 ; log_page_size++) {
- if ((1 << log_page_size) == PAGE_SIZE)
+ if ((1 << log_page_size) == QEDI_PAGE_SIZE)
break;
}
qedi->pf_params.iscsi_pf_params.log_page_size = log_page_size;
@@ -951,6 +987,9 @@ static int qedi_find_boot_info(struct qedi_ctx *qedi,
cls_sess = iscsi_conn_to_session(cls_conn);
sess = cls_sess->dd_data;
+ if (!iscsi_is_session_online(cls_sess))
+ continue;
+
if (pri_ctrl_flags) {
if (!strcmp(pri_tgt->iscsi_name, sess->targetname) &&
!strcmp(pri_tgt->ip_addr, ep_ip_addr)) {
@@ -1297,7 +1336,7 @@ static int qedi_request_msix_irq(struct qedi_ctx *qedi)
int i, rc, cpu;
cpu = cpumask_first(cpu_online_mask);
- for (i = 0; i < MIN_NUM_CPUS_MSIX(qedi); i++) {
+ for (i = 0; i < qedi->int_info.msix_cnt; i++) {
rc = request_irq(qedi->int_info.msix[i].vector,
qedi_msix_handler, 0, "qedi",
&qedi->fp_array[i]);
@@ -1375,7 +1414,7 @@ static void qedi_free_bdq(struct qedi_ctx *qedi)
int i;
if (qedi->bdq_pbl_list)
- dma_free_coherent(&qedi->pdev->dev, PAGE_SIZE,
+ dma_free_coherent(&qedi->pdev->dev, QEDI_PAGE_SIZE,
qedi->bdq_pbl_list, qedi->bdq_pbl_list_dma);
if (qedi->bdq_pbl)
@@ -1436,7 +1475,7 @@ static int qedi_alloc_bdq(struct qedi_ctx *qedi)
/* Alloc dma memory for BDQ page buffer list */
qedi->bdq_pbl_mem_size = QEDI_BDQ_NUM * sizeof(struct scsi_bd);
- qedi->bdq_pbl_mem_size = ALIGN(qedi->bdq_pbl_mem_size, PAGE_SIZE);
+ qedi->bdq_pbl_mem_size = ALIGN(qedi->bdq_pbl_mem_size, QEDI_PAGE_SIZE);
qedi->rq_num_entries = qedi->bdq_pbl_mem_size / sizeof(struct scsi_bd);
QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_CONN, "rq_num_entries = %d.\n",
@@ -1471,7 +1510,8 @@ static int qedi_alloc_bdq(struct qedi_ctx *qedi)
}
/* Allocate list of PBL pages */
- qedi->bdq_pbl_list = dma_zalloc_coherent(&qedi->pdev->dev, PAGE_SIZE,
+ qedi->bdq_pbl_list = dma_zalloc_coherent(&qedi->pdev->dev,
+ QEDI_PAGE_SIZE,
&qedi->bdq_pbl_list_dma,
GFP_KERNEL);
if (!qedi->bdq_pbl_list) {
@@ -1484,13 +1524,14 @@ static int qedi_alloc_bdq(struct qedi_ctx *qedi)
* Now populate PBL list with pages that contain pointers to the
* individual buffers.
*/
- qedi->bdq_pbl_list_num_entries = qedi->bdq_pbl_mem_size / PAGE_SIZE;
+ qedi->bdq_pbl_list_num_entries = qedi->bdq_pbl_mem_size /
+ QEDI_PAGE_SIZE;
list = (u64 *)qedi->bdq_pbl_list;
page = qedi->bdq_pbl_list_dma;
for (i = 0; i < qedi->bdq_pbl_list_num_entries; i++) {
*list = qedi->bdq_pbl_dma;
list++;
- page += PAGE_SIZE;
+ page += QEDI_PAGE_SIZE;
}
return 0;