1 /**********************************************************************
2 * Author: Cavium, Inc.
3 *
4 * Contact: support@cavium.com
5 * Please include "LiquidIO" in the subject.
6 *
7 * Copyright (c) 2003-2015 Cavium, Inc.
8 *
9 * This file is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License, Version 2, as
11 * published by the Free Software Foundation.
12 *
13 * This file is distributed in the hope that it will be useful, but
14 * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
15 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
16 * NONINFRINGEMENT. See the GNU General Public License for more
17 * details.
18 *
19 * This file may also be available under a different license from Cavium.
20 * Contact Cavium, Inc. for more information
21 **********************************************************************/
22 #include <linux/pci.h>
23 #include <linux/if_vlan.h>
24 #include "liquidio_common.h"
25 #include "octeon_droq.h"
26 #include "octeon_iq.h"
27 #include "response_manager.h"
28 #include "octeon_device.h"
29 #include "octeon_nic.h"
30 #include "octeon_main.h"
31 #include "octeon_network.h"
32
liquidio_set_feature(struct net_device * netdev,int cmd,u16 param1)33 int liquidio_set_feature(struct net_device *netdev, int cmd, u16 param1)
34 {
35 struct lio *lio = GET_LIO(netdev);
36 struct octeon_device *oct = lio->oct_dev;
37 struct octnic_ctrl_pkt nctrl;
38 int ret = 0;
39
40 memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt));
41
42 nctrl.ncmd.u64 = 0;
43 nctrl.ncmd.s.cmd = cmd;
44 nctrl.ncmd.s.param1 = param1;
45 nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
46 nctrl.wait_time = 100;
47 nctrl.netpndev = (u64)netdev;
48 nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
49
50 ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);
51 if (ret < 0) {
52 dev_err(&oct->pci_dev->dev, "Feature change failed in core (ret: 0x%x)\n",
53 ret);
54 }
55 return ret;
56 }
57
octeon_report_tx_completion_to_bql(void * txq,unsigned int pkts_compl,unsigned int bytes_compl)58 void octeon_report_tx_completion_to_bql(void *txq, unsigned int pkts_compl,
59 unsigned int bytes_compl)
60 {
61 struct netdev_queue *netdev_queue = txq;
62
63 netdev_tx_completed_queue(netdev_queue, pkts_compl, bytes_compl);
64 }
65
octeon_update_tx_completion_counters(void * buf,int reqtype,unsigned int * pkts_compl,unsigned int * bytes_compl)66 void octeon_update_tx_completion_counters(void *buf, int reqtype,
67 unsigned int *pkts_compl,
68 unsigned int *bytes_compl)
69 {
70 struct octnet_buf_free_info *finfo;
71 struct sk_buff *skb = NULL;
72 struct octeon_soft_command *sc;
73
74 switch (reqtype) {
75 case REQTYPE_NORESP_NET:
76 case REQTYPE_NORESP_NET_SG:
77 finfo = buf;
78 skb = finfo->skb;
79 break;
80
81 case REQTYPE_RESP_NET_SG:
82 case REQTYPE_RESP_NET:
83 sc = buf;
84 skb = sc->callback_arg;
85 break;
86
87 default:
88 return;
89 }
90
91 (*pkts_compl)++;
92 /*TODO, Use some other pound define to suggest
93 * the fact that iqs are not tied to netdevs
94 * and can take traffic from different netdevs
95 * hence bql reporting is done per packet
96 * than in bulk. Usage of NO_NAPI in txq completion is
97 * a little confusing
98 */
99 *bytes_compl += skb->len;
100 }
101
octeon_report_sent_bytes_to_bql(void * buf,int reqtype)102 void octeon_report_sent_bytes_to_bql(void *buf, int reqtype)
103 {
104 struct octnet_buf_free_info *finfo;
105 struct sk_buff *skb;
106 struct octeon_soft_command *sc;
107 struct netdev_queue *txq;
108
109 switch (reqtype) {
110 case REQTYPE_NORESP_NET:
111 case REQTYPE_NORESP_NET_SG:
112 finfo = buf;
113 skb = finfo->skb;
114 break;
115
116 case REQTYPE_RESP_NET_SG:
117 case REQTYPE_RESP_NET:
118 sc = buf;
119 skb = sc->callback_arg;
120 break;
121
122 default:
123 return;
124 }
125
126 txq = netdev_get_tx_queue(skb->dev, skb_get_queue_mapping(skb));
127 netdev_tx_sent_queue(txq, skb->len);
128 }
129
liquidio_link_ctrl_cmd_completion(void * nctrl_ptr)130 void liquidio_link_ctrl_cmd_completion(void *nctrl_ptr)
131 {
132 struct octnic_ctrl_pkt *nctrl = (struct octnic_ctrl_pkt *)nctrl_ptr;
133 struct net_device *netdev = (struct net_device *)nctrl->netpndev;
134 struct lio *lio = GET_LIO(netdev);
135 struct octeon_device *oct = lio->oct_dev;
136 u8 *mac;
137
138 switch (nctrl->ncmd.s.cmd) {
139 case OCTNET_CMD_CHANGE_DEVFLAGS:
140 case OCTNET_CMD_SET_MULTI_LIST:
141 break;
142
143 case OCTNET_CMD_CHANGE_MACADDR:
144 mac = ((u8 *)&nctrl->udd[0]) + 2;
145 netif_info(lio, probe, lio->netdev,
146 "MACAddr changed to %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
147 mac[0], mac[1],
148 mac[2], mac[3],
149 mac[4], mac[5]);
150 break;
151
152 case OCTNET_CMD_CHANGE_MTU:
153 /* If command is successful, change the MTU. */
154 netif_info(lio, probe, lio->netdev, "MTU Changed from %d to %d\n",
155 netdev->mtu, nctrl->ncmd.s.param1);
156 dev_info(&oct->pci_dev->dev, "%s MTU Changed from %d to %d\n",
157 netdev->name, netdev->mtu,
158 nctrl->ncmd.s.param1);
159 netdev->mtu = nctrl->ncmd.s.param1;
160 queue_delayed_work(lio->link_status_wq.wq,
161 &lio->link_status_wq.wk.work, 0);
162 break;
163
164 case OCTNET_CMD_GPIO_ACCESS:
165 netif_info(lio, probe, lio->netdev, "LED Flashing visual identification\n");
166
167 break;
168
169 case OCTNET_CMD_ID_ACTIVE:
170 netif_info(lio, probe, lio->netdev, "LED Flashing visual identification\n");
171
172 break;
173
174 case OCTNET_CMD_LRO_ENABLE:
175 dev_info(&oct->pci_dev->dev, "%s LRO Enabled\n", netdev->name);
176 break;
177
178 case OCTNET_CMD_LRO_DISABLE:
179 dev_info(&oct->pci_dev->dev, "%s LRO Disabled\n",
180 netdev->name);
181 break;
182
183 case OCTNET_CMD_VERBOSE_ENABLE:
184 dev_info(&oct->pci_dev->dev, "%s Firmware debug enabled\n",
185 netdev->name);
186 break;
187
188 case OCTNET_CMD_VERBOSE_DISABLE:
189 dev_info(&oct->pci_dev->dev, "%s Firmware debug disabled\n",
190 netdev->name);
191 break;
192
193 case OCTNET_CMD_ENABLE_VLAN_FILTER:
194 dev_info(&oct->pci_dev->dev, "%s VLAN filter enabled\n",
195 netdev->name);
196 break;
197
198 case OCTNET_CMD_ADD_VLAN_FILTER:
199 dev_info(&oct->pci_dev->dev, "%s VLAN filter %d added\n",
200 netdev->name, nctrl->ncmd.s.param1);
201 break;
202
203 case OCTNET_CMD_DEL_VLAN_FILTER:
204 dev_info(&oct->pci_dev->dev, "%s VLAN filter %d removed\n",
205 netdev->name, nctrl->ncmd.s.param1);
206 break;
207
208 case OCTNET_CMD_SET_SETTINGS:
209 dev_info(&oct->pci_dev->dev, "%s settings changed\n",
210 netdev->name);
211
212 break;
213
214 /* Case to handle "OCTNET_CMD_TNL_RX_CSUM_CTL"
215 * Command passed by NIC driver
216 */
217 case OCTNET_CMD_TNL_RX_CSUM_CTL:
218 if (nctrl->ncmd.s.param1 == OCTNET_CMD_RXCSUM_ENABLE) {
219 netif_info(lio, probe, lio->netdev,
220 "RX Checksum Offload Enabled\n");
221 } else if (nctrl->ncmd.s.param1 ==
222 OCTNET_CMD_RXCSUM_DISABLE) {
223 netif_info(lio, probe, lio->netdev,
224 "RX Checksum Offload Disabled\n");
225 }
226 break;
227
228 /* Case to handle "OCTNET_CMD_TNL_TX_CSUM_CTL"
229 * Command passed by NIC driver
230 */
231 case OCTNET_CMD_TNL_TX_CSUM_CTL:
232 if (nctrl->ncmd.s.param1 == OCTNET_CMD_TXCSUM_ENABLE) {
233 netif_info(lio, probe, lio->netdev,
234 "TX Checksum Offload Enabled\n");
235 } else if (nctrl->ncmd.s.param1 ==
236 OCTNET_CMD_TXCSUM_DISABLE) {
237 netif_info(lio, probe, lio->netdev,
238 "TX Checksum Offload Disabled\n");
239 }
240 break;
241
242 /* Case to handle "OCTNET_CMD_VXLAN_PORT_CONFIG"
243 * Command passed by NIC driver
244 */
245 case OCTNET_CMD_VXLAN_PORT_CONFIG:
246 if (nctrl->ncmd.s.more == OCTNET_CMD_VXLAN_PORT_ADD) {
247 netif_info(lio, probe, lio->netdev,
248 "VxLAN Destination UDP PORT:%d ADDED\n",
249 nctrl->ncmd.s.param1);
250 } else if (nctrl->ncmd.s.more ==
251 OCTNET_CMD_VXLAN_PORT_DEL) {
252 netif_info(lio, probe, lio->netdev,
253 "VxLAN Destination UDP PORT:%d DELETED\n",
254 nctrl->ncmd.s.param1);
255 }
256 break;
257
258 case OCTNET_CMD_SET_FLOW_CTL:
259 netif_info(lio, probe, lio->netdev, "Set RX/TX flow control parameters\n");
260 break;
261
262 default:
263 dev_err(&oct->pci_dev->dev, "%s Unknown cmd %d\n", __func__,
264 nctrl->ncmd.s.cmd);
265 }
266 }
267