brintos

brintos / linux-shallow public Read only

0
0
Text · 20.4 KiB · e0b173c Raw
948 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright 2008 Cisco Systems, Inc.  All rights reserved.4 * Copyright 2007 Nuova Systems, Inc.  All rights reserved.5 */6 7#include <linux/kernel.h>8#include <linux/errno.h>9#include <linux/types.h>10#include <linux/pci.h>11#include <linux/delay.h>12#include <linux/if_ether.h>13#include <linux/slab.h>14#include "vnic_resource.h"15#include "vnic_devcmd.h"16#include "vnic_dev.h"17#include "vnic_stats.h"18#include "vnic_wq.h"19 20struct devcmd2_controller {21	struct vnic_wq_ctrl *wq_ctrl;22	struct vnic_dev_ring results_ring;23	struct vnic_wq wq;24	struct vnic_devcmd2 *cmd_ring;25	struct devcmd2_result *result;26	u16 next_result;27	u16 result_size;28	int color;29};30 31enum vnic_proxy_type {32	PROXY_NONE,33	PROXY_BY_BDF,34	PROXY_BY_INDEX,35};36 37struct vnic_res {38	void __iomem *vaddr;39	unsigned int count;40};41 42struct vnic_dev {43	void *priv;44	struct pci_dev *pdev;45	struct vnic_res res[RES_TYPE_MAX];46	enum vnic_dev_intr_mode intr_mode;47	struct vnic_devcmd __iomem *devcmd;48	struct vnic_devcmd_notify *notify;49	struct vnic_devcmd_notify notify_copy;50	dma_addr_t notify_pa;51	u32 *linkstatus;52	dma_addr_t linkstatus_pa;53	struct vnic_stats *stats;54	dma_addr_t stats_pa;55	struct vnic_devcmd_fw_info *fw_info;56	dma_addr_t fw_info_pa;57	enum vnic_proxy_type proxy;58	u32 proxy_index;59	u64 args[VNIC_DEVCMD_NARGS];60	struct devcmd2_controller *devcmd2;61	int (*devcmd_rtn)(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,62			int wait);63};64 65#define VNIC_MAX_RES_HDR_SIZE \66	(sizeof(struct vnic_resource_header) + \67	sizeof(struct vnic_resource) * RES_TYPE_MAX)68#define VNIC_RES_STRIDE	12869 70void *vnic_dev_priv(struct vnic_dev *vdev)71{72	return vdev->priv;73}74 75static int vnic_dev_discover_res(struct vnic_dev *vdev,76	struct vnic_dev_bar *bar)77{78	struct vnic_resource_header __iomem *rh;79	struct vnic_resource __iomem *r;80	u8 type;81 82	if (bar->len < VNIC_MAX_RES_HDR_SIZE) {83		printk(KERN_ERR "vNIC BAR0 res hdr length error\n");84		return -EINVAL;85	}86 87	rh = bar->vaddr;88	if (!rh) {89		printk(KERN_ERR "vNIC BAR0 res hdr not mem-mapped\n");90		return -EINVAL;91	}92 93	if (ioread32(&rh->magic) != VNIC_RES_MAGIC ||94	    ioread32(&rh->version) != VNIC_RES_VERSION) {95		printk(KERN_ERR "vNIC BAR0 res magic/version error "96			"exp (%lx/%lx) curr (%x/%x)\n",97			VNIC_RES_MAGIC, VNIC_RES_VERSION,98			ioread32(&rh->magic), ioread32(&rh->version));99		return -EINVAL;100	}101 102	r = (struct vnic_resource __iomem *)(rh + 1);103 104	while ((type = ioread8(&r->type)) != RES_TYPE_EOL) {105 106		u8 bar_num = ioread8(&r->bar);107		u32 bar_offset = ioread32(&r->bar_offset);108		u32 count = ioread32(&r->count);109		u32 len;110 111		r++;112 113		if (bar_num != 0)  /* only mapping in BAR0 resources */114			continue;115 116		switch (type) {117		case RES_TYPE_WQ:118		case RES_TYPE_RQ:119		case RES_TYPE_CQ:120		case RES_TYPE_INTR_CTRL:121			/* each count is stride bytes long */122			len = count * VNIC_RES_STRIDE;123			if (len + bar_offset > bar->len) {124				printk(KERN_ERR "vNIC BAR0 resource %d "125					"out-of-bounds, offset 0x%x + "126					"size 0x%x > bar len 0x%lx\n",127					type, bar_offset,128					len,129					bar->len);130				return -EINVAL;131			}132			break;133		case RES_TYPE_INTR_PBA_LEGACY:134		case RES_TYPE_DEVCMD2:135		case RES_TYPE_DEVCMD:136			len = count;137			break;138		default:139			continue;140		}141 142		vdev->res[type].count = count;143		vdev->res[type].vaddr = (char __iomem *)bar->vaddr + bar_offset;144	}145 146	pr_info("res_type_wq: %d res_type_rq: %d res_type_cq: %d res_type_intr_ctrl: %d\n",147		vdev->res[RES_TYPE_WQ].count, vdev->res[RES_TYPE_RQ].count,148		vdev->res[RES_TYPE_CQ].count, vdev->res[RES_TYPE_INTR_CTRL].count);149 150	return 0;151}152 153unsigned int vnic_dev_get_res_count(struct vnic_dev *vdev,154	enum vnic_res_type type)155{156	return vdev->res[type].count;157}158 159void __iomem *vnic_dev_get_res(struct vnic_dev *vdev, enum vnic_res_type type,160	unsigned int index)161{162	if (!vdev->res[type].vaddr)163		return NULL;164 165	switch (type) {166	case RES_TYPE_WQ:167	case RES_TYPE_RQ:168	case RES_TYPE_CQ:169	case RES_TYPE_INTR_CTRL:170		return (char __iomem *)vdev->res[type].vaddr +171					index * VNIC_RES_STRIDE;172	default:173		return (char __iomem *)vdev->res[type].vaddr;174	}175}176 177unsigned int vnic_dev_desc_ring_size(struct vnic_dev_ring *ring,178				     unsigned int desc_count,179				     unsigned int desc_size)180{181	/* The base address of the desc rings must be 512 byte aligned.182	 * Descriptor count is aligned to groups of 32 descriptors.  A183	 * count of 0 means the maximum 4096 descriptors.  Descriptor184	 * size is aligned to 16 bytes.185	 */186 187	unsigned int count_align = 32;188	unsigned int desc_align = 16;189 190	ring->base_align = 512;191 192	if (desc_count == 0)193		desc_count = 4096;194 195	ring->desc_count = ALIGN(desc_count, count_align);196 197	ring->desc_size = ALIGN(desc_size, desc_align);198 199	ring->size = ring->desc_count * ring->desc_size;200	ring->size_unaligned = ring->size + ring->base_align;201 202	return ring->size_unaligned;203}204 205void vnic_dev_clear_desc_ring(struct vnic_dev_ring *ring)206{207	memset(ring->descs, 0, ring->size);208}209 210int vnic_dev_alloc_desc_ring(struct vnic_dev *vdev, struct vnic_dev_ring *ring,211	unsigned int desc_count, unsigned int desc_size)212{213	vnic_dev_desc_ring_size(ring, desc_count, desc_size);214 215	ring->descs_unaligned = dma_alloc_coherent(&vdev->pdev->dev,216		ring->size_unaligned,217		&ring->base_addr_unaligned, GFP_KERNEL);218 219	if (!ring->descs_unaligned) {220		printk(KERN_ERR221		  "Failed to allocate ring (size=%d), aborting\n",222			(int)ring->size);223		return -ENOMEM;224	}225 226	ring->base_addr = ALIGN(ring->base_addr_unaligned,227		ring->base_align);228	ring->descs = (u8 *)ring->descs_unaligned +229		(ring->base_addr - ring->base_addr_unaligned);230 231	vnic_dev_clear_desc_ring(ring);232 233	ring->desc_avail = ring->desc_count - 1;234 235	return 0;236}237 238void vnic_dev_free_desc_ring(struct vnic_dev *vdev, struct vnic_dev_ring *ring)239{240	if (ring->descs) {241		dma_free_coherent(&vdev->pdev->dev,242			ring->size_unaligned,243			ring->descs_unaligned,244			ring->base_addr_unaligned);245		ring->descs = NULL;246	}247}248 249static int vnic_dev_cmd1(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd, int wait)250{251	struct vnic_devcmd __iomem *devcmd = vdev->devcmd;252	int delay;253	u32 status;254	static const int dev_cmd_err[] = {255		/* convert from fw's version of error.h to host's version */256		0,	/* ERR_SUCCESS */257		EINVAL,	/* ERR_EINVAL */258		EFAULT,	/* ERR_EFAULT */259		EPERM,	/* ERR_EPERM */260		EBUSY,  /* ERR_EBUSY */261	};262	int err;263	u64 *a0 = &vdev->args[0];264	u64 *a1 = &vdev->args[1];265 266	status = ioread32(&devcmd->status);267	if (status & STAT_BUSY) {268		printk(KERN_ERR "Busy devcmd %d\n", _CMD_N(cmd));269		return -EBUSY;270	}271 272	if (_CMD_DIR(cmd) & _CMD_DIR_WRITE) {273		writeq(*a0, &devcmd->args[0]);274		writeq(*a1, &devcmd->args[1]);275		wmb();276	}277 278	iowrite32(cmd, &devcmd->cmd);279 280	if ((_CMD_FLAGS(cmd) & _CMD_FLAGS_NOWAIT))281			return 0;282 283	for (delay = 0; delay < wait; delay++) {284 285		udelay(100);286 287		status = ioread32(&devcmd->status);288		if (!(status & STAT_BUSY)) {289 290			if (status & STAT_ERROR) {291				err = dev_cmd_err[(int)readq(&devcmd->args[0])];292				printk(KERN_ERR "Error %d devcmd %d\n",293					err, _CMD_N(cmd));294				return -err;295			}296 297			if (_CMD_DIR(cmd) & _CMD_DIR_READ) {298				rmb();299				*a0 = readq(&devcmd->args[0]);300				*a1 = readq(&devcmd->args[1]);301			}302 303			return 0;304		}305	}306 307	printk(KERN_ERR "Timedout devcmd %d\n", _CMD_N(cmd));308	return -ETIMEDOUT;309}310 311static int vnic_dev_cmd2(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,312		int wait)313{314	struct devcmd2_controller *dc2c = vdev->devcmd2;315	struct devcmd2_result *result;316	u8 color;317	unsigned int i;318	int delay;319	int err;320	u32 fetch_index;321	u32 posted;322	u32 new_posted;323 324	posted = ioread32(&dc2c->wq_ctrl->posted_index);325	fetch_index = ioread32(&dc2c->wq_ctrl->fetch_index);326 327	if (posted == 0xFFFFFFFF || fetch_index == 0xFFFFFFFF) {328		/* Hardware surprise removal: return error */329		pr_err("%s: devcmd2 invalid posted or fetch index on cmd %d\n",330				pci_name(vdev->pdev), _CMD_N(cmd));331		pr_err("%s: fetch index: %u, posted index: %u\n",332				pci_name(vdev->pdev), fetch_index, posted);333 334		return -ENODEV;335 336	}337 338	new_posted = (posted + 1) % DEVCMD2_RING_SIZE;339 340	if (new_posted == fetch_index) {341		pr_err("%s: devcmd2 wq full while issuing cmd %d\n",342				pci_name(vdev->pdev), _CMD_N(cmd));343		pr_err("%s: fetch index: %u, posted index: %u\n",344				pci_name(vdev->pdev), fetch_index, posted);345		return -EBUSY;346 347	}348	dc2c->cmd_ring[posted].cmd = cmd;349	dc2c->cmd_ring[posted].flags = 0;350 351	if ((_CMD_FLAGS(cmd) & _CMD_FLAGS_NOWAIT))352		dc2c->cmd_ring[posted].flags |= DEVCMD2_FNORESULT;353	if (_CMD_DIR(cmd) & _CMD_DIR_WRITE) {354		for (i = 0; i < VNIC_DEVCMD_NARGS; i++)355			dc2c->cmd_ring[posted].args[i] = vdev->args[i];356 357	}358 359	/* Adding write memory barrier prevents compiler and/or CPU360	 * reordering, thus avoiding descriptor posting before361	 * descriptor is initialized. Otherwise, hardware can read362	 * stale descriptor fields.363	 */364	wmb();365	iowrite32(new_posted, &dc2c->wq_ctrl->posted_index);366 367	if (dc2c->cmd_ring[posted].flags & DEVCMD2_FNORESULT)368		return 0;369 370	result = dc2c->result + dc2c->next_result;371	color = dc2c->color;372 373	dc2c->next_result++;374	if (dc2c->next_result == dc2c->result_size) {375		dc2c->next_result = 0;376		dc2c->color = dc2c->color ? 0 : 1;377	}378 379	for (delay = 0; delay < wait; delay++) {380		udelay(100);381		if (result->color == color) {382			if (result->error) {383				err = -(int) result->error;384				if (err != ERR_ECMDUNKNOWN ||385						cmd != CMD_CAPABILITY)386					pr_err("%s:Error %d devcmd %d\n",387						pci_name(vdev->pdev),388						err, _CMD_N(cmd));389				return err;390			}391			if (_CMD_DIR(cmd) & _CMD_DIR_READ) {392				rmb(); /*prevent reorder while reding result*/393				for (i = 0; i < VNIC_DEVCMD_NARGS; i++)394					vdev->args[i] = result->results[i];395			}396			return 0;397		}398	}399 400	pr_err("%s:Timed out devcmd %d\n", pci_name(vdev->pdev), _CMD_N(cmd));401 402	return -ETIMEDOUT;403}404 405 406static int vnic_dev_init_devcmd1(struct vnic_dev *vdev)407{408	vdev->devcmd = vnic_dev_get_res(vdev, RES_TYPE_DEVCMD, 0);409	if (!vdev->devcmd)410		return -ENODEV;411 412	vdev->devcmd_rtn = &vnic_dev_cmd1;413	return 0;414}415 416 417static int vnic_dev_init_devcmd2(struct vnic_dev *vdev)418{419	int err;420	unsigned int fetch_index;421 422	if (vdev->devcmd2)423		return 0;424 425	vdev->devcmd2 = kzalloc(sizeof(*vdev->devcmd2), GFP_ATOMIC);426	if (!vdev->devcmd2)427		return -ENOMEM;428 429	vdev->devcmd2->color = 1;430	vdev->devcmd2->result_size = DEVCMD2_RING_SIZE;431	err = vnic_wq_devcmd2_alloc(vdev, &vdev->devcmd2->wq,432				DEVCMD2_RING_SIZE, DEVCMD2_DESC_SIZE);433	if (err)434		goto err_free_devcmd2;435 436	fetch_index = ioread32(&vdev->devcmd2->wq.ctrl->fetch_index);437	if (fetch_index == 0xFFFFFFFF) { /* check for hardware gone  */438		pr_err("error in devcmd2 init");439		err = -ENODEV;440		goto err_free_wq;441	}442 443	/*444	 * Don't change fetch_index ever and445	 * set posted_index same as fetch_index446	 * when setting up the WQ for devcmd2.447	 */448	vnic_wq_init_start(&vdev->devcmd2->wq, 0, fetch_index,449			fetch_index, 0, 0);450 451	vnic_wq_enable(&vdev->devcmd2->wq);452 453	err = vnic_dev_alloc_desc_ring(vdev, &vdev->devcmd2->results_ring,454			DEVCMD2_RING_SIZE, DEVCMD2_DESC_SIZE);455	if (err)456		goto err_disable_wq;457 458	vdev->devcmd2->result =459		(struct devcmd2_result *) vdev->devcmd2->results_ring.descs;460	vdev->devcmd2->cmd_ring =461		(struct vnic_devcmd2 *) vdev->devcmd2->wq.ring.descs;462	vdev->devcmd2->wq_ctrl = vdev->devcmd2->wq.ctrl;463	vdev->args[0] = (u64) vdev->devcmd2->results_ring.base_addr |464				VNIC_PADDR_TARGET;465	vdev->args[1] = DEVCMD2_RING_SIZE;466 467	err = vnic_dev_cmd2(vdev, CMD_INITIALIZE_DEVCMD2, 1000);468	if (err)469		goto err_free_desc_ring;470 471	vdev->devcmd_rtn = &vnic_dev_cmd2;472 473	return 0;474 475err_free_desc_ring:476	vnic_dev_free_desc_ring(vdev, &vdev->devcmd2->results_ring);477err_disable_wq:478	vnic_wq_disable(&vdev->devcmd2->wq);479err_free_wq:480	vnic_wq_free(&vdev->devcmd2->wq);481err_free_devcmd2:482	kfree(vdev->devcmd2);483	vdev->devcmd2 = NULL;484 485	return err;486}487 488 489static void vnic_dev_deinit_devcmd2(struct vnic_dev *vdev)490{491	vnic_dev_free_desc_ring(vdev, &vdev->devcmd2->results_ring);492	vnic_wq_disable(&vdev->devcmd2->wq);493	vnic_wq_free(&vdev->devcmd2->wq);494	kfree(vdev->devcmd2);495	vdev->devcmd2 = NULL;496	vdev->devcmd_rtn = &vnic_dev_cmd1;497}498 499 500static int vnic_dev_cmd_no_proxy(struct vnic_dev *vdev,501	enum vnic_devcmd_cmd cmd, u64 *a0, u64 *a1, int wait)502{503	int err;504 505	vdev->args[0] = *a0;506	vdev->args[1] = *a1;507 508	err = (*vdev->devcmd_rtn)(vdev, cmd, wait);509 510	*a0 = vdev->args[0];511	*a1 = vdev->args[1];512 513	return err;514}515 516 517int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,518	u64 *a0, u64 *a1, int wait)519{520	memset(vdev->args, 0, sizeof(vdev->args));521 522	switch (vdev->proxy) {523	case PROXY_NONE:524	default:525		return vnic_dev_cmd_no_proxy(vdev, cmd, a0, a1, wait);526	}527}528 529 530int vnic_dev_fw_info(struct vnic_dev *vdev,531	struct vnic_devcmd_fw_info **fw_info)532{533	u64 a0, a1 = 0;534	int wait = 1000;535	int err = 0;536 537	if (!vdev->fw_info) {538		vdev->fw_info = dma_alloc_coherent(&vdev->pdev->dev,539			sizeof(struct vnic_devcmd_fw_info),540			&vdev->fw_info_pa, GFP_KERNEL);541		if (!vdev->fw_info)542			return -ENOMEM;543 544		a0 = vdev->fw_info_pa;545 546		/* only get fw_info once and cache it */547		err = vnic_dev_cmd(vdev, CMD_MCPU_FW_INFO, &a0, &a1, wait);548	}549 550	*fw_info = vdev->fw_info;551 552	return err;553}554 555int vnic_dev_spec(struct vnic_dev *vdev, unsigned int offset, unsigned int size,556	void *value)557{558	u64 a0, a1;559	int wait = 1000;560	int err;561 562	a0 = offset;563	a1 = size;564 565	err = vnic_dev_cmd(vdev, CMD_DEV_SPEC, &a0, &a1, wait);566 567	switch (size) {568	case 1:569		*(u8 *)value = (u8)a0;570		break;571	case 2:572		*(u16 *)value = (u16)a0;573		break;574	case 4:575		*(u32 *)value = (u32)a0;576		break;577	case 8:578		*(u64 *)value = a0;579		break;580	default:581		BUG();582		break;583	}584 585	return err;586}587 588int vnic_dev_stats_clear(struct vnic_dev *vdev)589{590	u64 a0 = 0, a1 = 0;591	int wait = 1000;592	return vnic_dev_cmd(vdev, CMD_STATS_CLEAR, &a0, &a1, wait);593}594 595int vnic_dev_stats_dump(struct vnic_dev *vdev, struct vnic_stats **stats)596{597	u64 a0, a1;598	int wait = 1000;599 600	if (!vdev->stats) {601		vdev->stats = dma_alloc_coherent(&vdev->pdev->dev,602			sizeof(struct vnic_stats), &vdev->stats_pa, GFP_KERNEL);603		if (!vdev->stats)604			return -ENOMEM;605	}606 607	*stats = vdev->stats;608	a0 = vdev->stats_pa;609	a1 = sizeof(struct vnic_stats);610 611	return vnic_dev_cmd(vdev, CMD_STATS_DUMP, &a0, &a1, wait);612}613 614int vnic_dev_close(struct vnic_dev *vdev)615{616	u64 a0 = 0, a1 = 0;617	int wait = 1000;618	return vnic_dev_cmd(vdev, CMD_CLOSE, &a0, &a1, wait);619}620 621int vnic_dev_enable(struct vnic_dev *vdev)622{623	u64 a0 = 0, a1 = 0;624	int wait = 1000;625	return vnic_dev_cmd(vdev, CMD_ENABLE, &a0, &a1, wait);626}627 628int vnic_dev_disable(struct vnic_dev *vdev)629{630	u64 a0 = 0, a1 = 0;631	int wait = 1000;632	return vnic_dev_cmd(vdev, CMD_DISABLE, &a0, &a1, wait);633}634 635int vnic_dev_open(struct vnic_dev *vdev, int arg)636{637	u64 a0 = (u32)arg, a1 = 0;638	int wait = 1000;639	return vnic_dev_cmd(vdev, CMD_OPEN, &a0, &a1, wait);640}641 642int vnic_dev_open_done(struct vnic_dev *vdev, int *done)643{644	u64 a0 = 0, a1 = 0;645	int wait = 1000;646	int err;647 648	*done = 0;649 650	err = vnic_dev_cmd(vdev, CMD_OPEN_STATUS, &a0, &a1, wait);651	if (err)652		return err;653 654	*done = (a0 == 0);655 656	return 0;657}658 659int vnic_dev_soft_reset(struct vnic_dev *vdev, int arg)660{661	u64 a0 = (u32)arg, a1 = 0;662	int wait = 1000;663	return vnic_dev_cmd(vdev, CMD_SOFT_RESET, &a0, &a1, wait);664}665 666int vnic_dev_soft_reset_done(struct vnic_dev *vdev, int *done)667{668	u64 a0 = 0, a1 = 0;669	int wait = 1000;670	int err;671 672	*done = 0;673 674	err = vnic_dev_cmd(vdev, CMD_SOFT_RESET_STATUS, &a0, &a1, wait);675	if (err)676		return err;677 678	*done = (a0 == 0);679 680	return 0;681}682 683int vnic_dev_hang_notify(struct vnic_dev *vdev)684{685	u64 a0 = 0, a1 = 0;686	int wait = 1000;687	return vnic_dev_cmd(vdev, CMD_HANG_NOTIFY, &a0, &a1, wait);688}689 690int vnic_dev_mac_addr(struct vnic_dev *vdev, u8 *mac_addr)691{692	u64 a[2] = {};693	int wait = 1000;694	int err, i;695 696	for (i = 0; i < ETH_ALEN; i++)697		mac_addr[i] = 0;698 699	err = vnic_dev_cmd(vdev, CMD_MAC_ADDR, &a[0], &a[1], wait);700	if (err)701		return err;702 703	for (i = 0; i < ETH_ALEN; i++)704		mac_addr[i] = ((u8 *)&a)[i];705 706	return 0;707}708 709void vnic_dev_packet_filter(struct vnic_dev *vdev, int directed, int multicast,710	int broadcast, int promisc, int allmulti)711{712	u64 a0, a1 = 0;713	int wait = 1000;714	int err;715 716	a0 = (directed ? CMD_PFILTER_DIRECTED : 0) |717	     (multicast ? CMD_PFILTER_MULTICAST : 0) |718	     (broadcast ? CMD_PFILTER_BROADCAST : 0) |719	     (promisc ? CMD_PFILTER_PROMISCUOUS : 0) |720	     (allmulti ? CMD_PFILTER_ALL_MULTICAST : 0);721 722	err = vnic_dev_cmd(vdev, CMD_PACKET_FILTER, &a0, &a1, wait);723	if (err)724		printk(KERN_ERR "Can't set packet filter\n");725}726 727void vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr)728{729	u64 a[2] = {};730	int wait = 1000;731	int err;732	int i;733 734	for (i = 0; i < ETH_ALEN; i++)735		((u8 *)&a)[i] = addr[i];736 737	err = vnic_dev_cmd(vdev, CMD_ADDR_ADD, &a[0], &a[1], wait);738	if (err)739		pr_err("Can't add addr [%pM], %d\n", addr, err);740}741 742void vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr)743{744	u64 a[2] = {};745	int wait = 1000;746	int err;747	int i;748 749	for (i = 0; i < ETH_ALEN; i++)750		((u8 *)&a)[i] = addr[i];751 752	err = vnic_dev_cmd(vdev, CMD_ADDR_DEL, &a[0], &a[1], wait);753	if (err)754		pr_err("Can't del addr [%pM], %d\n", addr, err);755}756 757int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr)758{759	u64 a0, a1;760	int wait = 1000;761 762	if (!vdev->notify) {763		vdev->notify = dma_alloc_coherent(&vdev->pdev->dev,764			sizeof(struct vnic_devcmd_notify),765			&vdev->notify_pa, GFP_KERNEL);766		if (!vdev->notify)767			return -ENOMEM;768	}769 770	a0 = vdev->notify_pa;771	a1 = ((u64)intr << 32) & 0x0000ffff00000000ULL;772	a1 += sizeof(struct vnic_devcmd_notify);773 774	return vnic_dev_cmd(vdev, CMD_NOTIFY, &a0, &a1, wait);775}776 777void vnic_dev_notify_unset(struct vnic_dev *vdev)778{779	u64 a0, a1;780	int wait = 1000;781 782	a0 = 0;  /* paddr = 0 to unset notify buffer */783	a1 = 0x0000ffff00000000ULL; /* intr num = -1 to unreg for intr */784	a1 += sizeof(struct vnic_devcmd_notify);785 786	vnic_dev_cmd(vdev, CMD_NOTIFY, &a0, &a1, wait);787}788 789static int vnic_dev_notify_ready(struct vnic_dev *vdev)790{791	u32 *words;792	unsigned int nwords = sizeof(struct vnic_devcmd_notify) / 4;793	unsigned int i;794	u32 csum;795 796	if (!vdev->notify)797		return 0;798 799	do {800		csum = 0;801		memcpy(&vdev->notify_copy, vdev->notify,802			sizeof(struct vnic_devcmd_notify));803		words = (u32 *)&vdev->notify_copy;804		for (i = 1; i < nwords; i++)805			csum += words[i];806	} while (csum != words[0]);807 808	return 1;809}810 811int vnic_dev_init(struct vnic_dev *vdev, int arg)812{813	u64 a0 = (u32)arg, a1 = 0;814	int wait = 1000;815	return vnic_dev_cmd(vdev, CMD_INIT, &a0, &a1, wait);816}817 818u16 vnic_dev_set_default_vlan(struct vnic_dev *vdev, u16 new_default_vlan)819{820	u64 a0 = new_default_vlan, a1 = 0;821	int wait = 1000;822	int old_vlan = 0;823 824	old_vlan = vnic_dev_cmd(vdev, CMD_SET_DEFAULT_VLAN, &a0, &a1, wait);825	return (u16)old_vlan;826}827 828int vnic_dev_link_status(struct vnic_dev *vdev)829{830	if (vdev->linkstatus)831		return *vdev->linkstatus;832 833	if (!vnic_dev_notify_ready(vdev))834		return 0;835 836	return vdev->notify_copy.link_state;837}838 839u32 vnic_dev_port_speed(struct vnic_dev *vdev)840{841	if (!vnic_dev_notify_ready(vdev))842		return 0;843 844	return vdev->notify_copy.port_speed;845}846 847u32 vnic_dev_msg_lvl(struct vnic_dev *vdev)848{849	if (!vnic_dev_notify_ready(vdev))850		return 0;851 852	return vdev->notify_copy.msglvl;853}854 855u32 vnic_dev_mtu(struct vnic_dev *vdev)856{857	if (!vnic_dev_notify_ready(vdev))858		return 0;859 860	return vdev->notify_copy.mtu;861}862 863u32 vnic_dev_link_down_cnt(struct vnic_dev *vdev)864{865	if (!vnic_dev_notify_ready(vdev))866		return 0;867 868	return vdev->notify_copy.link_down_cnt;869}870 871void vnic_dev_set_intr_mode(struct vnic_dev *vdev,872	enum vnic_dev_intr_mode intr_mode)873{874	vdev->intr_mode = intr_mode;875}876 877enum vnic_dev_intr_mode vnic_dev_get_intr_mode(878	struct vnic_dev *vdev)879{880	return vdev->intr_mode;881}882 883void vnic_dev_unregister(struct vnic_dev *vdev)884{885	if (vdev) {886		if (vdev->notify)887			dma_free_coherent(&vdev->pdev->dev,888				sizeof(struct vnic_devcmd_notify),889				vdev->notify,890				vdev->notify_pa);891		if (vdev->linkstatus)892			dma_free_coherent(&vdev->pdev->dev,893				sizeof(u32),894				vdev->linkstatus,895				vdev->linkstatus_pa);896		if (vdev->stats)897			dma_free_coherent(&vdev->pdev->dev,898				sizeof(struct vnic_stats),899				vdev->stats, vdev->stats_pa);900		if (vdev->fw_info)901			dma_free_coherent(&vdev->pdev->dev,902				sizeof(struct vnic_devcmd_fw_info),903				vdev->fw_info, vdev->fw_info_pa);904		if (vdev->devcmd2)905			vnic_dev_deinit_devcmd2(vdev);906		kfree(vdev);907	}908}909 910struct vnic_dev *vnic_dev_register(struct vnic_dev *vdev,911	void *priv, struct pci_dev *pdev, struct vnic_dev_bar *bar)912{913	if (!vdev) {914		vdev = kzalloc(sizeof(struct vnic_dev), GFP_KERNEL);915		if (!vdev)916			return NULL;917	}918 919	vdev->priv = priv;920	vdev->pdev = pdev;921 922	if (vnic_dev_discover_res(vdev, bar))923		goto err_out;924 925	return vdev;926 927err_out:928	vnic_dev_unregister(vdev);929	return NULL;930}931 932int vnic_dev_cmd_init(struct vnic_dev *vdev)933{934	int err;935	void *p;936 937	p = vnic_dev_get_res(vdev, RES_TYPE_DEVCMD2, 0);938	if (p) {939		pr_err("fnic: DEVCMD2 resource found!\n");940		err = vnic_dev_init_devcmd2(vdev);941	} else {942		pr_err("fnic: DEVCMD2 not found, fall back to Devcmd\n");943		err = vnic_dev_init_devcmd1(vdev);944	}945 946	return err;947}948