15df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar/* 25df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar * Copyright 2008 Cisco Systems, Inc. All rights reserved. 35df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar * Copyright 2007 Nuova Systems, Inc. All rights reserved. 45df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar * 55df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar * This program is free software; you may redistribute it and/or modify 65df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar * it under the terms of the GNU General Public License as published by 75df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar * the Free Software Foundation; version 2 of the License. 85df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar * 95df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 105df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 115df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 125df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 135df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 145df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 155df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 165df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar * SOFTWARE. 175df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar */ 185df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar#ifndef _VNIC_WQ_COPY_H_ 195df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar#define _VNIC_WQ_COPY_H_ 205df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar 215df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar#include <linux/pci.h> 225df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar#include "vnic_wq.h" 235df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar#include "fcpio.h" 245df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar 255df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar#define VNIC_WQ_COPY_MAX 1 265df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar 275df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekarstruct vnic_wq_copy { 285df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar unsigned int index; 295df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar struct vnic_dev *vdev; 305df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar struct vnic_wq_ctrl __iomem *ctrl; /* memory-mapped */ 315df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar struct vnic_dev_ring ring; 325df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar unsigned to_use_index; 335df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar unsigned to_clean_index; 345df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar}; 355df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar 365df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekarstatic inline unsigned int vnic_wq_copy_desc_avail(struct vnic_wq_copy *wq) 375df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar{ 385df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar return wq->ring.desc_avail; 395df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar} 405df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar 415df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekarstatic inline unsigned int vnic_wq_copy_desc_in_use(struct vnic_wq_copy *wq) 425df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar{ 435df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar return wq->ring.desc_count - 1 - wq->ring.desc_avail; 445df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar} 455df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar 465df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekarstatic inline void *vnic_wq_copy_next_desc(struct vnic_wq_copy *wq) 475df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar{ 485df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar struct fcpio_host_req *desc = wq->ring.descs; 495df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar return &desc[wq->to_use_index]; 505df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar} 515df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar 525df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekarstatic inline void vnic_wq_copy_post(struct vnic_wq_copy *wq) 535df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar{ 545df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar 555df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar ((wq->to_use_index + 1) == wq->ring.desc_count) ? 565df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar (wq->to_use_index = 0) : (wq->to_use_index++); 575df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar wq->ring.desc_avail--; 585df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar 595df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar /* Adding write memory barrier prevents compiler and/or CPU 605df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar * reordering, thus avoiding descriptor posting before 615df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar * descriptor is initialized. Otherwise, hardware can read 625df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar * stale descriptor fields. 635df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar */ 645df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar wmb(); 655df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar 665df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar iowrite32(wq->to_use_index, &wq->ctrl->posted_index); 675df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar} 685df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar 695df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekarstatic inline void vnic_wq_copy_desc_process(struct vnic_wq_copy *wq, u16 index) 705df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar{ 715df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar unsigned int cnt; 725df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar 735df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar if (wq->to_clean_index <= index) 745df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar cnt = (index - wq->to_clean_index) + 1; 755df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar else 765df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar cnt = wq->ring.desc_count - wq->to_clean_index + index + 1; 775df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar 785df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar wq->to_clean_index = ((index + 1) % wq->ring.desc_count); 795df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar wq->ring.desc_avail += cnt; 805df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar 815df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar} 825df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar 835df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekarstatic inline void vnic_wq_copy_service(struct vnic_wq_copy *wq, 845df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar u16 completed_index, 855df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar void (*q_service)(struct vnic_wq_copy *wq, 865df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar struct fcpio_host_req *wq_desc)) 875df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar{ 885df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar struct fcpio_host_req *wq_desc = wq->ring.descs; 895df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar unsigned int curr_index; 905df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar 915df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar while (1) { 925df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar 935df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar if (q_service) 945df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar (*q_service)(wq, &wq_desc[wq->to_clean_index]); 955df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar 965df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar wq->ring.desc_avail++; 975df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar 985df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar curr_index = wq->to_clean_index; 995df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar 1005df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar /* increment the to-clean index so that we start 1015df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar * with an unprocessed index next time we enter the loop 1025df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar */ 1035df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar ((wq->to_clean_index + 1) == wq->ring.desc_count) ? 1045df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar (wq->to_clean_index = 0) : (wq->to_clean_index++); 1055df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar 1065df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar if (curr_index == completed_index) 1075df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar break; 1085df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar 1095df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar /* we have cleaned all the entries */ 1105df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar if ((completed_index == (u16)-1) && 1115df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar (wq->to_clean_index == wq->to_use_index)) 1125df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar break; 1135df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar } 1145df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar} 1155df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar 1165df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekarvoid vnic_wq_copy_enable(struct vnic_wq_copy *wq); 1175df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekarint vnic_wq_copy_disable(struct vnic_wq_copy *wq); 1185df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekarvoid vnic_wq_copy_free(struct vnic_wq_copy *wq); 1195df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekarint vnic_wq_copy_alloc(struct vnic_dev *vdev, struct vnic_wq_copy *wq, 1205df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar unsigned int index, unsigned int desc_count, unsigned int desc_size); 1215df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekarvoid vnic_wq_copy_init(struct vnic_wq_copy *wq, unsigned int cq_index, 1225df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar unsigned int error_interrupt_enable, 1235df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar unsigned int error_interrupt_offset); 1245df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekarvoid vnic_wq_copy_clean(struct vnic_wq_copy *wq, 1255df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar void (*q_clean)(struct vnic_wq_copy *wq, 1265df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar struct fcpio_host_req *wq_desc)); 1275df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar 1285df6d737dd4b0fe9eccf943abb3677cfea05a6c4Abhijeet Joglekar#endif /* _VNIC_WQ_COPY_H_ */ 129