1 // SPDX-License-Identifier: GPL-2.0 2 // Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved. 3 4 #include <linux/etherdevice.h> 5 #include <linux/netdevice.h> 6 7 #include "hinic3_common.h" 8 #include "hinic3_hw_comm.h" 9 #include "hinic3_hwdev.h" 10 #include "hinic3_hwif.h" 11 #include "hinic3_lld.h" 12 #include "hinic3_nic_cfg.h" 13 #include "hinic3_nic_dev.h" 14 #include "hinic3_nic_io.h" 15 #include "hinic3_rx.h" 16 #include "hinic3_tx.h" 17 18 #define HINIC3_NIC_DRV_DESC "Intelligent Network Interface Card Driver" 19 20 #define HINIC3_RX_BUF_LEN 2048 21 #define HINIC3_LRO_REPLENISH_THLD 256 22 #define HINIC3_NIC_DEV_WQ_NAME "hinic3_nic_dev_wq" 23 24 #define HINIC3_SQ_DEPTH 1024 25 #define HINIC3_RQ_DEPTH 1024 26 27 static int hinic3_alloc_txrxqs(struct net_device *netdev) 28 { 29 struct hinic3_nic_dev *nic_dev = netdev_priv(netdev); 30 struct hinic3_hwdev *hwdev = nic_dev->hwdev; 31 int err; 32 33 err = hinic3_alloc_txqs(netdev); 34 if (err) { 35 dev_err(hwdev->dev, "Failed to alloc txqs\n"); 36 return err; 37 } 38 39 err = hinic3_alloc_rxqs(netdev); 40 if (err) { 41 dev_err(hwdev->dev, "Failed to alloc rxqs\n"); 42 goto err_free_txqs; 43 } 44 45 return 0; 46 47 err_free_txqs: 48 hinic3_free_txqs(netdev); 49 50 return err; 51 } 52 53 static void hinic3_free_txrxqs(struct net_device *netdev) 54 { 55 hinic3_free_rxqs(netdev); 56 hinic3_free_txqs(netdev); 57 } 58 59 static int hinic3_init_nic_dev(struct net_device *netdev, 60 struct hinic3_hwdev *hwdev) 61 { 62 struct hinic3_nic_dev *nic_dev = netdev_priv(netdev); 63 struct pci_dev *pdev = hwdev->pdev; 64 65 nic_dev->netdev = netdev; 66 SET_NETDEV_DEV(netdev, &pdev->dev); 67 nic_dev->hwdev = hwdev; 68 nic_dev->pdev = pdev; 69 70 nic_dev->rx_buf_len = HINIC3_RX_BUF_LEN; 71 nic_dev->lro_replenish_thld = HINIC3_LRO_REPLENISH_THLD; 72 nic_dev->nic_svc_cap = hwdev->cfg_mgmt->cap.nic_svc_cap; 73 74 return 0; 75 } 76 77 static int hinic3_sw_init(struct net_device *netdev) 78 { 79 struct hinic3_nic_dev *nic_dev = netdev_priv(netdev); 80 struct hinic3_hwdev *hwdev = nic_dev->hwdev; 81 int err; 82 83 nic_dev->q_params.sq_depth = HINIC3_SQ_DEPTH; 84 nic_dev->q_params.rq_depth = HINIC3_RQ_DEPTH; 85 86 /* VF driver always uses random MAC address. During VM migration to a 87 * new device, the new device should learn the VMs old MAC rather than 88 * provide its own MAC. The product design assumes that every VF is 89 * suspectable to migration so the device avoids offering MAC address 90 * to VFs. 91 */ 92 eth_hw_addr_random(netdev); 93 err = hinic3_set_mac(hwdev, netdev->dev_addr, 0, 94 hinic3_global_func_id(hwdev)); 95 if (err) { 96 dev_err(hwdev->dev, "Failed to set default MAC\n"); 97 return err; 98 } 99 100 err = hinic3_alloc_txrxqs(netdev); 101 if (err) { 102 dev_err(hwdev->dev, "Failed to alloc qps\n"); 103 goto err_del_mac; 104 } 105 106 return 0; 107 108 err_del_mac: 109 hinic3_del_mac(hwdev, netdev->dev_addr, 0, 110 hinic3_global_func_id(hwdev)); 111 112 return err; 113 } 114 115 static void hinic3_sw_uninit(struct net_device *netdev) 116 { 117 struct hinic3_nic_dev *nic_dev = netdev_priv(netdev); 118 119 hinic3_free_txrxqs(netdev); 120 hinic3_del_mac(nic_dev->hwdev, netdev->dev_addr, 0, 121 hinic3_global_func_id(nic_dev->hwdev)); 122 } 123 124 static void hinic3_assign_netdev_ops(struct net_device *netdev) 125 { 126 hinic3_set_netdev_ops(netdev); 127 } 128 129 static void netdev_feature_init(struct net_device *netdev) 130 { 131 struct hinic3_nic_dev *nic_dev = netdev_priv(netdev); 132 netdev_features_t cso_fts = 0; 133 netdev_features_t tso_fts = 0; 134 netdev_features_t dft_fts; 135 136 dft_fts = NETIF_F_SG | NETIF_F_HIGHDMA; 137 if (hinic3_test_support(nic_dev, HINIC3_NIC_F_CSUM)) 138 cso_fts |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM; 139 if (hinic3_test_support(nic_dev, HINIC3_NIC_F_SCTP_CRC)) 140 cso_fts |= NETIF_F_SCTP_CRC; 141 if (hinic3_test_support(nic_dev, HINIC3_NIC_F_TSO)) 142 tso_fts |= NETIF_F_TSO | NETIF_F_TSO6; 143 144 netdev->features |= dft_fts | cso_fts | tso_fts; 145 } 146 147 static int hinic3_set_default_hw_feature(struct net_device *netdev) 148 { 149 struct hinic3_nic_dev *nic_dev = netdev_priv(netdev); 150 struct hinic3_hwdev *hwdev = nic_dev->hwdev; 151 int err; 152 153 err = hinic3_set_nic_feature_to_hw(nic_dev); 154 if (err) { 155 dev_err(hwdev->dev, "Failed to set nic features\n"); 156 return err; 157 } 158 159 return 0; 160 } 161 162 static void hinic3_link_status_change(struct net_device *netdev, 163 bool link_status_up) 164 { 165 struct hinic3_nic_dev *nic_dev = netdev_priv(netdev); 166 167 if (link_status_up) { 168 if (netif_carrier_ok(netdev)) 169 return; 170 171 nic_dev->link_status_up = true; 172 netif_carrier_on(netdev); 173 netdev_dbg(netdev, "Link is up\n"); 174 } else { 175 if (!netif_carrier_ok(netdev)) 176 return; 177 178 nic_dev->link_status_up = false; 179 netif_carrier_off(netdev); 180 netdev_dbg(netdev, "Link is down\n"); 181 } 182 } 183 184 static void hinic3_nic_event(struct auxiliary_device *adev, 185 struct hinic3_event_info *event) 186 { 187 struct hinic3_nic_dev *nic_dev = dev_get_drvdata(&adev->dev); 188 struct net_device *netdev; 189 190 netdev = nic_dev->netdev; 191 192 switch (HINIC3_SRV_EVENT_TYPE(event->service, event->type)) { 193 case HINIC3_SRV_EVENT_TYPE(HINIC3_EVENT_SRV_NIC, 194 HINIC3_NIC_EVENT_LINK_UP): 195 hinic3_link_status_change(netdev, true); 196 break; 197 case HINIC3_SRV_EVENT_TYPE(HINIC3_EVENT_SRV_NIC, 198 HINIC3_NIC_EVENT_LINK_DOWN): 199 hinic3_link_status_change(netdev, false); 200 break; 201 default: 202 break; 203 } 204 } 205 206 static int hinic3_nic_probe(struct auxiliary_device *adev, 207 const struct auxiliary_device_id *id) 208 { 209 struct hinic3_hwdev *hwdev = hinic3_adev_get_hwdev(adev); 210 struct pci_dev *pdev = hwdev->pdev; 211 struct hinic3_nic_dev *nic_dev; 212 struct net_device *netdev; 213 u16 max_qps, glb_func_id; 214 int err; 215 216 if (!hinic3_support_nic(hwdev)) { 217 dev_dbg(&adev->dev, "HW doesn't support nic\n"); 218 return 0; 219 } 220 221 hinic3_adev_event_register(adev, hinic3_nic_event); 222 223 glb_func_id = hinic3_global_func_id(hwdev); 224 err = hinic3_func_reset(hwdev, glb_func_id, COMM_FUNC_RESET_BIT_NIC); 225 if (err) { 226 dev_err(&adev->dev, "Failed to reset function\n"); 227 goto err_unregister_adev_event; 228 } 229 230 max_qps = hinic3_func_max_qnum(hwdev); 231 netdev = alloc_etherdev_mq(sizeof(*nic_dev), max_qps); 232 if (!netdev) { 233 dev_err(&adev->dev, "Failed to allocate netdev\n"); 234 err = -ENOMEM; 235 goto err_unregister_adev_event; 236 } 237 238 nic_dev = netdev_priv(netdev); 239 dev_set_drvdata(&adev->dev, nic_dev); 240 err = hinic3_init_nic_dev(netdev, hwdev); 241 if (err) 242 goto err_free_netdev; 243 244 err = hinic3_init_nic_io(nic_dev); 245 if (err) 246 goto err_free_netdev; 247 248 err = hinic3_sw_init(netdev); 249 if (err) 250 goto err_free_nic_io; 251 252 hinic3_assign_netdev_ops(netdev); 253 254 netdev_feature_init(netdev); 255 err = hinic3_set_default_hw_feature(netdev); 256 if (err) 257 goto err_uninit_sw; 258 259 netif_carrier_off(netdev); 260 261 err = register_netdev(netdev); 262 if (err) 263 goto err_uninit_nic_feature; 264 265 return 0; 266 267 err_uninit_nic_feature: 268 hinic3_update_nic_feature(nic_dev, 0); 269 hinic3_set_nic_feature_to_hw(nic_dev); 270 271 err_uninit_sw: 272 hinic3_sw_uninit(netdev); 273 274 err_free_nic_io: 275 hinic3_free_nic_io(nic_dev); 276 277 err_free_netdev: 278 free_netdev(netdev); 279 280 err_unregister_adev_event: 281 hinic3_adev_event_unregister(adev); 282 dev_err(&pdev->dev, "NIC service probe failed\n"); 283 284 return err; 285 } 286 287 static void hinic3_nic_remove(struct auxiliary_device *adev) 288 { 289 struct hinic3_nic_dev *nic_dev = dev_get_drvdata(&adev->dev); 290 struct net_device *netdev; 291 292 if (!hinic3_support_nic(nic_dev->hwdev)) 293 return; 294 295 netdev = nic_dev->netdev; 296 unregister_netdev(netdev); 297 298 hinic3_update_nic_feature(nic_dev, 0); 299 hinic3_set_nic_feature_to_hw(nic_dev); 300 hinic3_sw_uninit(netdev); 301 302 hinic3_free_nic_io(nic_dev); 303 304 free_netdev(netdev); 305 } 306 307 static const struct auxiliary_device_id hinic3_nic_id_table[] = { 308 { 309 .name = HINIC3_NIC_DRV_NAME ".nic", 310 }, 311 {} 312 }; 313 314 static struct auxiliary_driver hinic3_nic_driver = { 315 .probe = hinic3_nic_probe, 316 .remove = hinic3_nic_remove, 317 .suspend = NULL, 318 .resume = NULL, 319 .name = "nic", 320 .id_table = hinic3_nic_id_table, 321 }; 322 323 static __init int hinic3_nic_lld_init(void) 324 { 325 int err; 326 327 err = hinic3_lld_init(); 328 if (err) 329 return err; 330 331 err = auxiliary_driver_register(&hinic3_nic_driver); 332 if (err) { 333 hinic3_lld_exit(); 334 return err; 335 } 336 337 return 0; 338 } 339 340 static __exit void hinic3_nic_lld_exit(void) 341 { 342 auxiliary_driver_unregister(&hinic3_nic_driver); 343 344 hinic3_lld_exit(); 345 } 346 347 module_init(hinic3_nic_lld_init); 348 module_exit(hinic3_nic_lld_exit); 349 350 MODULE_AUTHOR("Huawei Technologies CO., Ltd"); 351 MODULE_DESCRIPTION(HINIC3_NIC_DRV_DESC); 352 MODULE_LICENSE("GPL"); 353