1a6a5580cSJeff Kirsher /*
2a6a5580cSJeff Kirsher  * Copyright 2011 Cisco Systems, Inc.  All rights reserved.
3a6a5580cSJeff Kirsher  *
4a6a5580cSJeff Kirsher  * This program is free software; you may redistribute it and/or modify
5a6a5580cSJeff Kirsher  * it under the terms of the GNU General Public License as published by
6a6a5580cSJeff Kirsher  * the Free Software Foundation; version 2 of the License.
7a6a5580cSJeff Kirsher  *
8a6a5580cSJeff Kirsher  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
9a6a5580cSJeff Kirsher  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
10a6a5580cSJeff Kirsher  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
11a6a5580cSJeff Kirsher  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
12a6a5580cSJeff Kirsher  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
13a6a5580cSJeff Kirsher  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
14a6a5580cSJeff Kirsher  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
15a6a5580cSJeff Kirsher  * SOFTWARE.
16a6a5580cSJeff Kirsher  *
17a6a5580cSJeff Kirsher  */
18a6a5580cSJeff Kirsher 
19a6a5580cSJeff Kirsher #include <linux/pci.h>
20a6a5580cSJeff Kirsher #include <linux/etherdevice.h>
21a6a5580cSJeff Kirsher 
22a6a5580cSJeff Kirsher #include "vnic_dev.h"
23a6a5580cSJeff Kirsher #include "vnic_vic.h"
24a6a5580cSJeff Kirsher #include "enic_res.h"
25a6a5580cSJeff Kirsher #include "enic.h"
26a6a5580cSJeff Kirsher #include "enic_dev.h"
27a6a5580cSJeff Kirsher 
28a6a5580cSJeff Kirsher int enic_dev_fw_info(struct enic *enic, struct vnic_devcmd_fw_info **fw_info)
29a6a5580cSJeff Kirsher {
30a6a5580cSJeff Kirsher 	int err;
31a6a5580cSJeff Kirsher 
32a6a5580cSJeff Kirsher 	spin_lock(&enic->devcmd_lock);
33a6a5580cSJeff Kirsher 	err = vnic_dev_fw_info(enic->vdev, fw_info);
34a6a5580cSJeff Kirsher 	spin_unlock(&enic->devcmd_lock);
35a6a5580cSJeff Kirsher 
36a6a5580cSJeff Kirsher 	return err;
37a6a5580cSJeff Kirsher }
38a6a5580cSJeff Kirsher 
39a6a5580cSJeff Kirsher int enic_dev_stats_dump(struct enic *enic, struct vnic_stats **vstats)
40a6a5580cSJeff Kirsher {
41a6a5580cSJeff Kirsher 	int err;
42a6a5580cSJeff Kirsher 
43a6a5580cSJeff Kirsher 	spin_lock(&enic->devcmd_lock);
44a6a5580cSJeff Kirsher 	err = vnic_dev_stats_dump(enic->vdev, vstats);
45a6a5580cSJeff Kirsher 	spin_unlock(&enic->devcmd_lock);
46a6a5580cSJeff Kirsher 
47a6a5580cSJeff Kirsher 	return err;
48a6a5580cSJeff Kirsher }
49a6a5580cSJeff Kirsher 
50a6a5580cSJeff Kirsher int enic_dev_add_station_addr(struct enic *enic)
51a6a5580cSJeff Kirsher {
52a6a5580cSJeff Kirsher 	int err;
53a6a5580cSJeff Kirsher 
54a6a5580cSJeff Kirsher 	if (!is_valid_ether_addr(enic->netdev->dev_addr))
55a6a5580cSJeff Kirsher 		return -EADDRNOTAVAIL;
56a6a5580cSJeff Kirsher 
57a6a5580cSJeff Kirsher 	spin_lock(&enic->devcmd_lock);
58a6a5580cSJeff Kirsher 	err = vnic_dev_add_addr(enic->vdev, enic->netdev->dev_addr);
59a6a5580cSJeff Kirsher 	spin_unlock(&enic->devcmd_lock);
60a6a5580cSJeff Kirsher 
61a6a5580cSJeff Kirsher 	return err;
62a6a5580cSJeff Kirsher }
63a6a5580cSJeff Kirsher 
64a6a5580cSJeff Kirsher int enic_dev_del_station_addr(struct enic *enic)
65a6a5580cSJeff Kirsher {
66a6a5580cSJeff Kirsher 	int err;
67a6a5580cSJeff Kirsher 
68a6a5580cSJeff Kirsher 	if (!is_valid_ether_addr(enic->netdev->dev_addr))
69a6a5580cSJeff Kirsher 		return -EADDRNOTAVAIL;
70a6a5580cSJeff Kirsher 
71a6a5580cSJeff Kirsher 	spin_lock(&enic->devcmd_lock);
72a6a5580cSJeff Kirsher 	err = vnic_dev_del_addr(enic->vdev, enic->netdev->dev_addr);
73a6a5580cSJeff Kirsher 	spin_unlock(&enic->devcmd_lock);
74a6a5580cSJeff Kirsher 
75a6a5580cSJeff Kirsher 	return err;
76a6a5580cSJeff Kirsher }
77a6a5580cSJeff Kirsher 
78a6a5580cSJeff Kirsher int enic_dev_packet_filter(struct enic *enic, int directed, int multicast,
79a6a5580cSJeff Kirsher 	int broadcast, int promisc, int allmulti)
80a6a5580cSJeff Kirsher {
81a6a5580cSJeff Kirsher 	int err;
82a6a5580cSJeff Kirsher 
83a6a5580cSJeff Kirsher 	spin_lock(&enic->devcmd_lock);
84a6a5580cSJeff Kirsher 	err = vnic_dev_packet_filter(enic->vdev, directed,
85a6a5580cSJeff Kirsher 		multicast, broadcast, promisc, allmulti);
86a6a5580cSJeff Kirsher 	spin_unlock(&enic->devcmd_lock);
87a6a5580cSJeff Kirsher 
88a6a5580cSJeff Kirsher 	return err;
89a6a5580cSJeff Kirsher }
90a6a5580cSJeff Kirsher 
91a6a5580cSJeff Kirsher int enic_dev_add_addr(struct enic *enic, u8 *addr)
92a6a5580cSJeff Kirsher {
93a6a5580cSJeff Kirsher 	int err;
94a6a5580cSJeff Kirsher 
95a6a5580cSJeff Kirsher 	spin_lock(&enic->devcmd_lock);
96a6a5580cSJeff Kirsher 	err = vnic_dev_add_addr(enic->vdev, addr);
97a6a5580cSJeff Kirsher 	spin_unlock(&enic->devcmd_lock);
98a6a5580cSJeff Kirsher 
99a6a5580cSJeff Kirsher 	return err;
100a6a5580cSJeff Kirsher }
101a6a5580cSJeff Kirsher 
102a6a5580cSJeff Kirsher int enic_dev_del_addr(struct enic *enic, u8 *addr)
103a6a5580cSJeff Kirsher {
104a6a5580cSJeff Kirsher 	int err;
105a6a5580cSJeff Kirsher 
106a6a5580cSJeff Kirsher 	spin_lock(&enic->devcmd_lock);
107a6a5580cSJeff Kirsher 	err = vnic_dev_del_addr(enic->vdev, addr);
108a6a5580cSJeff Kirsher 	spin_unlock(&enic->devcmd_lock);
109a6a5580cSJeff Kirsher 
110a6a5580cSJeff Kirsher 	return err;
111a6a5580cSJeff Kirsher }
112a6a5580cSJeff Kirsher 
113a6a5580cSJeff Kirsher int enic_dev_notify_unset(struct enic *enic)
114a6a5580cSJeff Kirsher {
115a6a5580cSJeff Kirsher 	int err;
116a6a5580cSJeff Kirsher 
117a6a5580cSJeff Kirsher 	spin_lock(&enic->devcmd_lock);
118a6a5580cSJeff Kirsher 	err = vnic_dev_notify_unset(enic->vdev);
119a6a5580cSJeff Kirsher 	spin_unlock(&enic->devcmd_lock);
120a6a5580cSJeff Kirsher 
121a6a5580cSJeff Kirsher 	return err;
122a6a5580cSJeff Kirsher }
123a6a5580cSJeff Kirsher 
124a6a5580cSJeff Kirsher int enic_dev_hang_notify(struct enic *enic)
125a6a5580cSJeff Kirsher {
126a6a5580cSJeff Kirsher 	int err;
127a6a5580cSJeff Kirsher 
128a6a5580cSJeff Kirsher 	spin_lock(&enic->devcmd_lock);
129a6a5580cSJeff Kirsher 	err = vnic_dev_hang_notify(enic->vdev);
130a6a5580cSJeff Kirsher 	spin_unlock(&enic->devcmd_lock);
131a6a5580cSJeff Kirsher 
132a6a5580cSJeff Kirsher 	return err;
133a6a5580cSJeff Kirsher }
134a6a5580cSJeff Kirsher 
135a6a5580cSJeff Kirsher int enic_dev_set_ig_vlan_rewrite_mode(struct enic *enic)
136a6a5580cSJeff Kirsher {
137a6a5580cSJeff Kirsher 	int err;
138a6a5580cSJeff Kirsher 
139a6a5580cSJeff Kirsher 	spin_lock(&enic->devcmd_lock);
140a6a5580cSJeff Kirsher 	err = vnic_dev_set_ig_vlan_rewrite_mode(enic->vdev,
141a6a5580cSJeff Kirsher 		IG_VLAN_REWRITE_MODE_PRIORITY_TAG_DEFAULT_VLAN);
142a6a5580cSJeff Kirsher 	spin_unlock(&enic->devcmd_lock);
143a6a5580cSJeff Kirsher 
144a6a5580cSJeff Kirsher 	return err;
145a6a5580cSJeff Kirsher }
146a6a5580cSJeff Kirsher 
147a6a5580cSJeff Kirsher int enic_dev_enable(struct enic *enic)
148a6a5580cSJeff Kirsher {
149a6a5580cSJeff Kirsher 	int err;
150a6a5580cSJeff Kirsher 
151a6a5580cSJeff Kirsher 	spin_lock(&enic->devcmd_lock);
152a6a5580cSJeff Kirsher 	err = vnic_dev_enable_wait(enic->vdev);
153a6a5580cSJeff Kirsher 	spin_unlock(&enic->devcmd_lock);
154a6a5580cSJeff Kirsher 
155a6a5580cSJeff Kirsher 	return err;
156a6a5580cSJeff Kirsher }
157a6a5580cSJeff Kirsher 
158a6a5580cSJeff Kirsher int enic_dev_disable(struct enic *enic)
159a6a5580cSJeff Kirsher {
160a6a5580cSJeff Kirsher 	int err;
161a6a5580cSJeff Kirsher 
162a6a5580cSJeff Kirsher 	spin_lock(&enic->devcmd_lock);
163a6a5580cSJeff Kirsher 	err = vnic_dev_disable(enic->vdev);
164a6a5580cSJeff Kirsher 	spin_unlock(&enic->devcmd_lock);
165a6a5580cSJeff Kirsher 
166a6a5580cSJeff Kirsher 	return err;
167a6a5580cSJeff Kirsher }
168a6a5580cSJeff Kirsher 
169a6a5580cSJeff Kirsher int enic_dev_intr_coal_timer_info(struct enic *enic)
170a6a5580cSJeff Kirsher {
171a6a5580cSJeff Kirsher 	int err;
172a6a5580cSJeff Kirsher 
173a6a5580cSJeff Kirsher 	spin_lock(&enic->devcmd_lock);
174a6a5580cSJeff Kirsher 	err = vnic_dev_intr_coal_timer_info(enic->vdev);
175a6a5580cSJeff Kirsher 	spin_unlock(&enic->devcmd_lock);
176a6a5580cSJeff Kirsher 
177a6a5580cSJeff Kirsher 	return err;
178a6a5580cSJeff Kirsher }
179a6a5580cSJeff Kirsher 
180a6a5580cSJeff Kirsher int enic_vnic_dev_deinit(struct enic *enic)
181a6a5580cSJeff Kirsher {
182a6a5580cSJeff Kirsher 	int err;
183a6a5580cSJeff Kirsher 
184a6a5580cSJeff Kirsher 	spin_lock(&enic->devcmd_lock);
185a6a5580cSJeff Kirsher 	err = vnic_dev_deinit(enic->vdev);
186a6a5580cSJeff Kirsher 	spin_unlock(&enic->devcmd_lock);
187a6a5580cSJeff Kirsher 
188a6a5580cSJeff Kirsher 	return err;
189a6a5580cSJeff Kirsher }
190a6a5580cSJeff Kirsher 
191a6a5580cSJeff Kirsher int enic_dev_init_prov2(struct enic *enic, struct vic_provinfo *vp)
192a6a5580cSJeff Kirsher {
193a6a5580cSJeff Kirsher 	int err;
194a6a5580cSJeff Kirsher 
195a6a5580cSJeff Kirsher 	spin_lock(&enic->devcmd_lock);
196a6a5580cSJeff Kirsher 	err = vnic_dev_init_prov2(enic->vdev,
197a6a5580cSJeff Kirsher 		(u8 *)vp, vic_provinfo_size(vp));
198a6a5580cSJeff Kirsher 	spin_unlock(&enic->devcmd_lock);
199a6a5580cSJeff Kirsher 
200a6a5580cSJeff Kirsher 	return err;
201a6a5580cSJeff Kirsher }
202a6a5580cSJeff Kirsher 
203a6a5580cSJeff Kirsher int enic_dev_deinit_done(struct enic *enic, int *status)
204a6a5580cSJeff Kirsher {
205a6a5580cSJeff Kirsher 	int err;
206a6a5580cSJeff Kirsher 
207a6a5580cSJeff Kirsher 	spin_lock(&enic->devcmd_lock);
208a6a5580cSJeff Kirsher 	err = vnic_dev_deinit_done(enic->vdev, status);
209a6a5580cSJeff Kirsher 	spin_unlock(&enic->devcmd_lock);
210a6a5580cSJeff Kirsher 
211a6a5580cSJeff Kirsher 	return err;
212a6a5580cSJeff Kirsher }
213a6a5580cSJeff Kirsher 
214a6a5580cSJeff Kirsher /* rtnl lock is held */
215a6a5580cSJeff Kirsher void enic_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
216a6a5580cSJeff Kirsher {
217a6a5580cSJeff Kirsher 	struct enic *enic = netdev_priv(netdev);
218a6a5580cSJeff Kirsher 
219a6a5580cSJeff Kirsher 	spin_lock(&enic->devcmd_lock);
220a6a5580cSJeff Kirsher 	enic_add_vlan(enic, vid);
221a6a5580cSJeff Kirsher 	spin_unlock(&enic->devcmd_lock);
222a6a5580cSJeff Kirsher }
223a6a5580cSJeff Kirsher 
224a6a5580cSJeff Kirsher /* rtnl lock is held */
225a6a5580cSJeff Kirsher void enic_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
226a6a5580cSJeff Kirsher {
227a6a5580cSJeff Kirsher 	struct enic *enic = netdev_priv(netdev);
228a6a5580cSJeff Kirsher 
229a6a5580cSJeff Kirsher 	spin_lock(&enic->devcmd_lock);
230a6a5580cSJeff Kirsher 	enic_del_vlan(enic, vid);
231a6a5580cSJeff Kirsher 	spin_unlock(&enic->devcmd_lock);
232a6a5580cSJeff Kirsher }
233a6a5580cSJeff Kirsher 
234a6a5580cSJeff Kirsher int enic_dev_enable2(struct enic *enic, int active)
235a6a5580cSJeff Kirsher {
236a6a5580cSJeff Kirsher 	int err;
237a6a5580cSJeff Kirsher 
238a6a5580cSJeff Kirsher 	spin_lock(&enic->devcmd_lock);
239a6a5580cSJeff Kirsher 	err = vnic_dev_enable2(enic->vdev, active);
240a6a5580cSJeff Kirsher 	spin_unlock(&enic->devcmd_lock);
241a6a5580cSJeff Kirsher 
242a6a5580cSJeff Kirsher 	return err;
243a6a5580cSJeff Kirsher }
244a6a5580cSJeff Kirsher 
245a6a5580cSJeff Kirsher int enic_dev_enable2_done(struct enic *enic, int *status)
246a6a5580cSJeff Kirsher {
247a6a5580cSJeff Kirsher 	int err;
248a6a5580cSJeff Kirsher 
249a6a5580cSJeff Kirsher 	spin_lock(&enic->devcmd_lock);
250a6a5580cSJeff Kirsher 	err = vnic_dev_enable2_done(enic->vdev, status);
251a6a5580cSJeff Kirsher 	spin_unlock(&enic->devcmd_lock);
252a6a5580cSJeff Kirsher 
253a6a5580cSJeff Kirsher 	return err;
254a6a5580cSJeff Kirsher }
255a6a5580cSJeff Kirsher 
256a6a5580cSJeff Kirsher int enic_dev_status_to_errno(int devcmd_status)
257a6a5580cSJeff Kirsher {
258a6a5580cSJeff Kirsher 	switch (devcmd_status) {
259a6a5580cSJeff Kirsher 	case ERR_SUCCESS:
260a6a5580cSJeff Kirsher 		return 0;
261a6a5580cSJeff Kirsher 	case ERR_EINVAL:
262a6a5580cSJeff Kirsher 		return -EINVAL;
263a6a5580cSJeff Kirsher 	case ERR_EFAULT:
264a6a5580cSJeff Kirsher 		return -EFAULT;
265a6a5580cSJeff Kirsher 	case ERR_EPERM:
266a6a5580cSJeff Kirsher 		return -EPERM;
267a6a5580cSJeff Kirsher 	case ERR_EBUSY:
268a6a5580cSJeff Kirsher 		return -EBUSY;
269a6a5580cSJeff Kirsher 	case ERR_ECMDUNKNOWN:
270a6a5580cSJeff Kirsher 	case ERR_ENOTSUPPORTED:
271a6a5580cSJeff Kirsher 		return -EOPNOTSUPP;
272a6a5580cSJeff Kirsher 	case ERR_EBADSTATE:
273a6a5580cSJeff Kirsher 		return -EINVAL;
274a6a5580cSJeff Kirsher 	case ERR_ENOMEM:
275a6a5580cSJeff Kirsher 		return -ENOMEM;
276a6a5580cSJeff Kirsher 	case ERR_ETIMEDOUT:
277a6a5580cSJeff Kirsher 		return -ETIMEDOUT;
278a6a5580cSJeff Kirsher 	case ERR_ELINKDOWN:
279a6a5580cSJeff Kirsher 		return -ENETDOWN;
280a6a5580cSJeff Kirsher 	case ERR_EINPROGRESS:
281a6a5580cSJeff Kirsher 		return -EINPROGRESS;
282a6a5580cSJeff Kirsher 	case ERR_EMAXRES:
283a6a5580cSJeff Kirsher 	default:
284a6a5580cSJeff Kirsher 		return (devcmd_status < 0) ? devcmd_status : -1;
285a6a5580cSJeff Kirsher 	}
286a6a5580cSJeff Kirsher }
287