1 // SPDX-License-Identifier: GPL-2.0 2 /* Marvell Octeon EP (EndPoint) Ethernet Driver 3 * 4 * Copyright (C) 2020 Marvell. 5 * 6 */ 7 #include <linux/string.h> 8 #include <linux/types.h> 9 #include <linux/etherdevice.h> 10 #include <linux/pci.h> 11 #include <linux/wait.h> 12 13 #include "octep_config.h" 14 #include "octep_main.h" 15 #include "octep_ctrl_net.h" 16 #include "octep_pfvf_mbox.h" 17 18 /* Control plane version */ 19 #define OCTEP_CP_VERSION_CURRENT OCTEP_CP_VERSION(1, 0, 0) 20 21 static const u32 req_hdr_sz = sizeof(union octep_ctrl_net_req_hdr); 22 static const u32 mtu_sz = sizeof(struct octep_ctrl_net_h2f_req_cmd_mtu); 23 static const u32 mac_sz = sizeof(struct octep_ctrl_net_h2f_req_cmd_mac); 24 static const u32 state_sz = sizeof(struct octep_ctrl_net_h2f_req_cmd_state); 25 static const u32 link_info_sz = sizeof(struct octep_ctrl_net_link_info); 26 static const u32 offloads_sz = sizeof(struct octep_ctrl_net_offloads); 27 static atomic_t ctrl_net_msg_id; 28 29 /* Control plane version in which OCTEP_CTRL_NET_H2F_CMD was added */ 30 static const u32 octep_ctrl_net_h2f_cmd_versions[OCTEP_CTRL_NET_H2F_CMD_MAX] = { 31 [OCTEP_CTRL_NET_H2F_CMD_INVALID ... OCTEP_CTRL_NET_H2F_CMD_DEV_REMOVE] = 32 OCTEP_CP_VERSION(1, 0, 0), 33 [OCTEP_CTRL_NET_H2F_CMD_OFFLOADS] = OCTEP_CP_VERSION(1, 0, 1) 34 35 }; 36 37 /* Control plane version in which OCTEP_CTRL_NET_F2H_CMD was added */ 38 static const u32 octep_ctrl_net_f2h_cmd_versions[OCTEP_CTRL_NET_F2H_CMD_MAX] = { 39 [OCTEP_CTRL_NET_F2H_CMD_INVALID ... OCTEP_CTRL_NET_F2H_CMD_LINK_STATUS] = 40 OCTEP_CP_VERSION(1, 0, 0) 41 }; 42 43 static void init_send_req(struct octep_ctrl_mbox_msg *msg, void *buf, 44 u16 sz, int vfid) 45 { 46 msg->hdr.s.flags = OCTEP_CTRL_MBOX_MSG_HDR_FLAG_REQ; 47 msg->hdr.s.msg_id = atomic_inc_return(&ctrl_net_msg_id) & 48 GENMASK(sizeof(msg->hdr.s.msg_id) * BITS_PER_BYTE, 0); 49 msg->hdr.s.sz = req_hdr_sz + sz; 50 msg->sg_num = 1; 51 msg->sg_list[0].msg = buf; 52 msg->sg_list[0].sz = msg->hdr.s.sz; 53 if (vfid != OCTEP_CTRL_NET_INVALID_VFID) { 54 msg->hdr.s.is_vf = 1; 55 msg->hdr.s.vf_idx = vfid; 56 } 57 } 58 59 static int octep_send_mbox_req(struct octep_device *oct, 60 struct octep_ctrl_net_wait_data *d, 61 bool wait_for_response) 62 { 63 int err, ret, cmd; 64 65 /* check if firmware is compatible for this request */ 66 cmd = d->data.req.hdr.s.cmd; 67 if (octep_ctrl_net_h2f_cmd_versions[cmd] > oct->ctrl_mbox.max_fw_version || 68 octep_ctrl_net_h2f_cmd_versions[cmd] < oct->ctrl_mbox.min_fw_version) 69 return -EOPNOTSUPP; 70 71 err = octep_ctrl_mbox_send(&oct->ctrl_mbox, &d->msg); 72 if (err < 0) 73 return err; 74 75 if (!wait_for_response) 76 return 0; 77 78 d->done = 0; 79 INIT_LIST_HEAD(&d->list); 80 list_add_tail(&d->list, &oct->ctrl_req_wait_list); 81 ret = wait_event_interruptible_timeout(oct->ctrl_req_wait_q, 82 (d->done != 0), 83 msecs_to_jiffies(500)); 84 list_del(&d->list); 85 if (ret == 0 || ret == 1) 86 return -EAGAIN; 87 88 /** 89 * (ret == 0) cond = false && timeout, return 0 90 * (ret < 0) interrupted by signal, return 0 91 * (ret == 1) cond = true && timeout, return 1 92 * (ret >= 1) cond = true && !timeout, return 1 93 */ 94 95 if (d->data.resp.hdr.s.reply != OCTEP_CTRL_NET_REPLY_OK) 96 return -EAGAIN; 97 98 return 0; 99 } 100 101 int octep_ctrl_net_init(struct octep_device *oct) 102 { 103 struct octep_ctrl_mbox *ctrl_mbox; 104 struct pci_dev *pdev = oct->pdev; 105 int ret; 106 107 init_waitqueue_head(&oct->ctrl_req_wait_q); 108 INIT_LIST_HEAD(&oct->ctrl_req_wait_list); 109 110 /* Initialize control mbox */ 111 ctrl_mbox = &oct->ctrl_mbox; 112 ctrl_mbox->version = OCTEP_CP_VERSION_CURRENT; 113 ctrl_mbox->barmem = CFG_GET_CTRL_MBOX_MEM_ADDR(oct->conf); 114 ret = octep_ctrl_mbox_init(ctrl_mbox); 115 if (ret) { 116 dev_err(&pdev->dev, "Failed to initialize control mbox\n"); 117 return ret; 118 } 119 dev_info(&pdev->dev, "Control plane versions host: %llx, firmware: %x:%x\n", 120 ctrl_mbox->version, ctrl_mbox->min_fw_version, 121 ctrl_mbox->max_fw_version); 122 oct->ctrl_mbox_ifstats_offset = ctrl_mbox->barmem_sz; 123 124 return 0; 125 } 126 127 int octep_ctrl_net_get_link_status(struct octep_device *oct, int vfid) 128 { 129 struct octep_ctrl_net_wait_data d = {}; 130 struct octep_ctrl_net_h2f_req *req = &d.data.req; 131 int err; 132 133 init_send_req(&d.msg, (void *)req, state_sz, vfid); 134 req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_LINK_STATUS; 135 req->link.cmd = OCTEP_CTRL_NET_CMD_GET; 136 err = octep_send_mbox_req(oct, &d, true); 137 if (err < 0) 138 return err; 139 140 return d.data.resp.link.state; 141 } 142 143 int octep_ctrl_net_set_link_status(struct octep_device *oct, int vfid, bool up, 144 bool wait_for_response) 145 { 146 struct octep_ctrl_net_wait_data d = {}; 147 struct octep_ctrl_net_h2f_req *req = &d.data.req; 148 149 init_send_req(&d.msg, req, state_sz, vfid); 150 req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_LINK_STATUS; 151 req->link.cmd = OCTEP_CTRL_NET_CMD_SET; 152 req->link.state = (up) ? OCTEP_CTRL_NET_STATE_UP : 153 OCTEP_CTRL_NET_STATE_DOWN; 154 155 return octep_send_mbox_req(oct, &d, wait_for_response); 156 } 157 158 int octep_ctrl_net_set_rx_state(struct octep_device *oct, int vfid, bool up, 159 bool wait_for_response) 160 { 161 struct octep_ctrl_net_wait_data d = {}; 162 struct octep_ctrl_net_h2f_req *req = &d.data.req; 163 164 init_send_req(&d.msg, req, state_sz, vfid); 165 req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_RX_STATE; 166 req->link.cmd = OCTEP_CTRL_NET_CMD_SET; 167 req->link.state = (up) ? OCTEP_CTRL_NET_STATE_UP : 168 OCTEP_CTRL_NET_STATE_DOWN; 169 170 return octep_send_mbox_req(oct, &d, wait_for_response); 171 } 172 173 int octep_ctrl_net_get_mac_addr(struct octep_device *oct, int vfid, u8 *addr) 174 { 175 struct octep_ctrl_net_wait_data d = {}; 176 struct octep_ctrl_net_h2f_req *req = &d.data.req; 177 int err; 178 179 init_send_req(&d.msg, req, mac_sz, vfid); 180 req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_MAC; 181 req->link.cmd = OCTEP_CTRL_NET_CMD_GET; 182 err = octep_send_mbox_req(oct, &d, true); 183 if (err < 0) 184 return err; 185 186 memcpy(addr, d.data.resp.mac.addr, ETH_ALEN); 187 188 return 0; 189 } 190 191 int octep_ctrl_net_set_mac_addr(struct octep_device *oct, int vfid, u8 *addr, 192 bool wait_for_response) 193 { 194 struct octep_ctrl_net_wait_data d = {}; 195 struct octep_ctrl_net_h2f_req *req = &d.data.req; 196 197 init_send_req(&d.msg, req, mac_sz, vfid); 198 req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_MAC; 199 req->mac.cmd = OCTEP_CTRL_NET_CMD_SET; 200 memcpy(&req->mac.addr, addr, ETH_ALEN); 201 202 return octep_send_mbox_req(oct, &d, wait_for_response); 203 } 204 205 int octep_ctrl_net_get_mtu(struct octep_device *oct, int vfid) 206 { 207 struct octep_ctrl_net_wait_data d = {}; 208 struct octep_ctrl_net_h2f_req *req; 209 int err; 210 211 req = &d.data.req; 212 init_send_req(&d.msg, req, mtu_sz, vfid); 213 req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_MTU; 214 req->mtu.cmd = OCTEP_CTRL_NET_CMD_GET; 215 216 err = octep_send_mbox_req(oct, &d, true); 217 if (err < 0) 218 return err; 219 220 return d.data.resp.mtu.val; 221 } 222 223 int octep_ctrl_net_set_mtu(struct octep_device *oct, int vfid, int mtu, 224 bool wait_for_response) 225 { 226 struct octep_ctrl_net_wait_data d = {}; 227 struct octep_ctrl_net_h2f_req *req = &d.data.req; 228 229 init_send_req(&d.msg, req, mtu_sz, vfid); 230 req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_MTU; 231 req->mtu.cmd = OCTEP_CTRL_NET_CMD_SET; 232 req->mtu.val = mtu; 233 234 return octep_send_mbox_req(oct, &d, wait_for_response); 235 } 236 237 int octep_ctrl_net_get_if_stats(struct octep_device *oct, int vfid, 238 struct octep_iface_rx_stats *rx_stats, 239 struct octep_iface_tx_stats *tx_stats) 240 { 241 struct octep_ctrl_net_wait_data d = {}; 242 struct octep_ctrl_net_h2f_req *req = &d.data.req; 243 struct octep_ctrl_net_h2f_resp *resp; 244 int err; 245 246 init_send_req(&d.msg, req, 0, vfid); 247 req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_GET_IF_STATS; 248 err = octep_send_mbox_req(oct, &d, true); 249 if (err < 0) 250 return err; 251 252 resp = &d.data.resp; 253 memcpy(rx_stats, &resp->if_stats.rx_stats, sizeof(struct octep_iface_rx_stats)); 254 memcpy(tx_stats, &resp->if_stats.tx_stats, sizeof(struct octep_iface_tx_stats)); 255 return 0; 256 } 257 258 int octep_ctrl_net_get_link_info(struct octep_device *oct, int vfid, 259 struct octep_iface_link_info *link_info) 260 { 261 struct octep_ctrl_net_wait_data d = {}; 262 struct octep_ctrl_net_h2f_req *req = &d.data.req; 263 struct octep_ctrl_net_h2f_resp *resp; 264 int err; 265 266 init_send_req(&d.msg, req, link_info_sz, vfid); 267 req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_LINK_INFO; 268 req->link_info.cmd = OCTEP_CTRL_NET_CMD_GET; 269 err = octep_send_mbox_req(oct, &d, true); 270 if (err < 0) 271 return err; 272 273 resp = &d.data.resp; 274 link_info->supported_modes = resp->link_info.supported_modes; 275 link_info->advertised_modes = resp->link_info.advertised_modes; 276 link_info->autoneg = resp->link_info.autoneg; 277 link_info->pause = resp->link_info.pause; 278 link_info->speed = resp->link_info.speed; 279 280 return 0; 281 } 282 283 int octep_ctrl_net_set_link_info(struct octep_device *oct, int vfid, 284 struct octep_iface_link_info *link_info, 285 bool wait_for_response) 286 { 287 struct octep_ctrl_net_wait_data d = {}; 288 struct octep_ctrl_net_h2f_req *req = &d.data.req; 289 290 init_send_req(&d.msg, req, link_info_sz, vfid); 291 req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_LINK_INFO; 292 req->link_info.cmd = OCTEP_CTRL_NET_CMD_SET; 293 req->link_info.info.advertised_modes = link_info->advertised_modes; 294 req->link_info.info.autoneg = link_info->autoneg; 295 req->link_info.info.pause = link_info->pause; 296 req->link_info.info.speed = link_info->speed; 297 298 return octep_send_mbox_req(oct, &d, wait_for_response); 299 } 300 301 static void process_mbox_resp(struct octep_device *oct, 302 struct octep_ctrl_mbox_msg *msg) 303 { 304 struct octep_ctrl_net_wait_data *pos, *n; 305 306 list_for_each_entry_safe(pos, n, &oct->ctrl_req_wait_list, list) { 307 if (pos->msg.hdr.s.msg_id == msg->hdr.s.msg_id) { 308 memcpy(&pos->data.resp, 309 msg->sg_list[0].msg, 310 msg->hdr.s.sz); 311 pos->done = 1; 312 wake_up_interruptible_all(&oct->ctrl_req_wait_q); 313 break; 314 } 315 } 316 } 317 318 static int process_mbox_notify(struct octep_device *oct, 319 struct octep_ctrl_mbox_msg *msg) 320 { 321 struct net_device *netdev = oct->netdev; 322 struct octep_ctrl_net_f2h_req *req; 323 int cmd; 324 325 req = (struct octep_ctrl_net_f2h_req *)msg->sg_list[0].msg; 326 cmd = req->hdr.s.cmd; 327 328 /* check if we support this command */ 329 if (octep_ctrl_net_f2h_cmd_versions[cmd] > OCTEP_CP_VERSION_CURRENT || 330 octep_ctrl_net_f2h_cmd_versions[cmd] < OCTEP_CP_VERSION_CURRENT) 331 return -EOPNOTSUPP; 332 333 if (msg->hdr.s.is_vf) { 334 octep_pfvf_notify(oct, msg); 335 return 0; 336 } 337 338 switch (cmd) { 339 case OCTEP_CTRL_NET_F2H_CMD_LINK_STATUS: 340 if (netif_running(netdev)) { 341 if (req->link.state) { 342 dev_info(&oct->pdev->dev, "netif_carrier_on\n"); 343 netif_carrier_on(netdev); 344 } else { 345 dev_info(&oct->pdev->dev, "netif_carrier_off\n"); 346 netif_carrier_off(netdev); 347 } 348 } 349 break; 350 default: 351 pr_info("Unknown mbox req : %u\n", req->hdr.s.cmd); 352 break; 353 } 354 355 return 0; 356 } 357 358 void octep_ctrl_net_recv_fw_messages(struct octep_device *oct) 359 { 360 static u16 msg_sz = sizeof(union octep_ctrl_net_max_data); 361 union octep_ctrl_net_max_data data = {}; 362 struct octep_ctrl_mbox_msg msg = {}; 363 int ret; 364 365 msg.hdr.s.sz = msg_sz; 366 msg.sg_num = 1; 367 msg.sg_list[0].sz = msg_sz; 368 msg.sg_list[0].msg = &data; 369 while (true) { 370 /* mbox will overwrite msg.hdr.s.sz so initialize it */ 371 msg.hdr.s.sz = msg_sz; 372 ret = octep_ctrl_mbox_recv(&oct->ctrl_mbox, (struct octep_ctrl_mbox_msg *)&msg); 373 if (ret < 0) 374 break; 375 376 if (msg.hdr.s.flags & OCTEP_CTRL_MBOX_MSG_HDR_FLAG_RESP) 377 process_mbox_resp(oct, &msg); 378 else if (msg.hdr.s.flags & OCTEP_CTRL_MBOX_MSG_HDR_FLAG_NOTIFY) 379 process_mbox_notify(oct, &msg); 380 } 381 } 382 383 int octep_ctrl_net_get_info(struct octep_device *oct, int vfid, 384 struct octep_fw_info *info) 385 { 386 struct octep_ctrl_net_wait_data d = {}; 387 struct octep_ctrl_net_h2f_resp *resp; 388 struct octep_ctrl_net_h2f_req *req; 389 int err; 390 391 req = &d.data.req; 392 init_send_req(&d.msg, req, 0, vfid); 393 req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_GET_INFO; 394 req->link_info.cmd = OCTEP_CTRL_NET_CMD_GET; 395 err = octep_send_mbox_req(oct, &d, true); 396 if (err < 0) 397 return err; 398 399 resp = &d.data.resp; 400 memcpy(info, &resp->info.fw_info, sizeof(struct octep_fw_info)); 401 402 return 0; 403 } 404 405 int octep_ctrl_net_dev_remove(struct octep_device *oct, int vfid) 406 { 407 struct octep_ctrl_net_wait_data d = {}; 408 struct octep_ctrl_net_h2f_req *req; 409 410 req = &d.data.req; 411 dev_dbg(&oct->pdev->dev, "Sending dev_unload msg to fw\n"); 412 init_send_req(&d.msg, req, sizeof(int), vfid); 413 req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_DEV_REMOVE; 414 415 return octep_send_mbox_req(oct, &d, false); 416 } 417 418 int octep_ctrl_net_set_offloads(struct octep_device *oct, int vfid, 419 struct octep_ctrl_net_offloads *offloads, 420 bool wait_for_response) 421 { 422 struct octep_ctrl_net_wait_data d = {}; 423 struct octep_ctrl_net_h2f_req *req; 424 425 req = &d.data.req; 426 init_send_req(&d.msg, req, offloads_sz, vfid); 427 req->hdr.s.cmd = OCTEP_CTRL_NET_H2F_CMD_OFFLOADS; 428 req->offloads.cmd = OCTEP_CTRL_NET_CMD_SET; 429 req->offloads.offloads = *offloads; 430 431 return octep_send_mbox_req(oct, &d, wait_for_response); 432 } 433 434 int octep_ctrl_net_uninit(struct octep_device *oct) 435 { 436 struct octep_ctrl_net_wait_data *pos, *n; 437 438 octep_ctrl_net_dev_remove(oct, OCTEP_CTRL_NET_INVALID_VFID); 439 440 list_for_each_entry_safe(pos, n, &oct->ctrl_req_wait_list, list) 441 pos->done = 1; 442 443 wake_up_interruptible_all(&oct->ctrl_req_wait_q); 444 445 octep_ctrl_mbox_uninit(&oct->ctrl_mbox); 446 447 return 0; 448 } 449