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