]> git.proxmox.com Git - mirror_ubuntu-eoan-kernel.git/blame - drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
Doc: hisi: hns adds mc-mac-mask property
[mirror_ubuntu-eoan-kernel.git] / drivers / net / ethernet / hisilicon / hns / hns_dsaf_mac.c
CommitLineData
511e6bc0 1/*
2 * Copyright (c) 2014-2015 Hisilicon Limited.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 */
9
1d1afa2e 10#include <linux/acpi.h>
511e6bc0 11#include <linux/init.h>
511e6bc0 12#include <linux/interrupt.h>
2e2591b1 13#include <linux/kernel.h>
831d828b 14#include <linux/mfd/syscon.h>
2e2591b1
DH
15#include <linux/module.h>
16#include <linux/netdevice.h>
511e6bc0 17#include <linux/of.h>
18#include <linux/of_address.h>
652d39b0
KY
19#include <linux/of_mdio.h>
20#include <linux/phy.h>
2e2591b1 21#include <linux/platform_device.h>
511e6bc0 22
511e6bc0 23#include "hns_dsaf_main.h"
2e2591b1 24#include "hns_dsaf_misc.h"
511e6bc0 25#include "hns_dsaf_rcb.h"
26
27#define MAC_EN_FLAG_V 0xada0328
28
29static const u16 mac_phy_to_speed[] = {
30 [PHY_INTERFACE_MODE_MII] = MAC_SPEED_100,
31 [PHY_INTERFACE_MODE_GMII] = MAC_SPEED_1000,
32 [PHY_INTERFACE_MODE_SGMII] = MAC_SPEED_1000,
33 [PHY_INTERFACE_MODE_TBI] = MAC_SPEED_1000,
34 [PHY_INTERFACE_MODE_RMII] = MAC_SPEED_100,
35 [PHY_INTERFACE_MODE_RGMII] = MAC_SPEED_1000,
36 [PHY_INTERFACE_MODE_RGMII_ID] = MAC_SPEED_1000,
37 [PHY_INTERFACE_MODE_RGMII_RXID] = MAC_SPEED_1000,
38 [PHY_INTERFACE_MODE_RGMII_TXID] = MAC_SPEED_1000,
39 [PHY_INTERFACE_MODE_RTBI] = MAC_SPEED_1000,
40 [PHY_INTERFACE_MODE_XGMII] = MAC_SPEED_10000
41};
42
43static const enum mac_mode g_mac_mode_100[] = {
44 [PHY_INTERFACE_MODE_MII] = MAC_MODE_MII_100,
45 [PHY_INTERFACE_MODE_RMII] = MAC_MODE_RMII_100
46};
47
48static const enum mac_mode g_mac_mode_1000[] = {
49 [PHY_INTERFACE_MODE_GMII] = MAC_MODE_GMII_1000,
50 [PHY_INTERFACE_MODE_SGMII] = MAC_MODE_SGMII_1000,
51 [PHY_INTERFACE_MODE_TBI] = MAC_MODE_TBI_1000,
52 [PHY_INTERFACE_MODE_RGMII] = MAC_MODE_RGMII_1000,
53 [PHY_INTERFACE_MODE_RGMII_ID] = MAC_MODE_RGMII_1000,
54 [PHY_INTERFACE_MODE_RGMII_RXID] = MAC_MODE_RGMII_1000,
55 [PHY_INTERFACE_MODE_RGMII_TXID] = MAC_MODE_RGMII_1000,
56 [PHY_INTERFACE_MODE_RTBI] = MAC_MODE_RTBI_1000
57};
58
511e6bc0 59static enum mac_mode hns_get_enet_interface(const struct hns_mac_cb *mac_cb)
60{
61 switch (mac_cb->max_speed) {
62 case MAC_SPEED_100:
63 return g_mac_mode_100[mac_cb->phy_if];
64 case MAC_SPEED_1000:
65 return g_mac_mode_1000[mac_cb->phy_if];
66 case MAC_SPEED_10000:
67 return MAC_MODE_XGMII_10000;
68 default:
69 return MAC_MODE_MII_100;
70 }
71}
72
511e6bc0 73void hns_mac_get_link_status(struct hns_mac_cb *mac_cb, u32 *link_status)
74{
75 struct mac_driver *mac_ctrl_drv;
76 int ret, sfp_prsnt;
77
78 mac_ctrl_drv = hns_mac_get_drv(mac_cb);
79
80 if (mac_ctrl_drv->get_link_status)
81 mac_ctrl_drv->get_link_status(mac_ctrl_drv, link_status);
82 else
83 *link_status = 0;
84
a24274aa 85 ret = mac_cb->dsaf_dev->misc_op->get_sfp_prsnt(mac_cb, &sfp_prsnt);
511e6bc0 86 if (!ret)
87 *link_status = *link_status && sfp_prsnt;
88
89 mac_cb->link = *link_status;
90}
91
92int hns_mac_get_port_info(struct hns_mac_cb *mac_cb,
93 u8 *auto_neg, u16 *speed, u8 *duplex)
94{
95 struct mac_driver *mac_ctrl_drv;
96 struct mac_info info;
97
98 mac_ctrl_drv = hns_mac_get_drv(mac_cb);
99
100 if (!mac_ctrl_drv->get_info)
101 return -ENODEV;
102
103 mac_ctrl_drv->get_info(mac_ctrl_drv, &info);
104 if (auto_neg)
105 *auto_neg = info.auto_neg;
106 if (speed)
107 *speed = info.speed;
108 if (duplex)
109 *duplex = info.duplex;
110
111 return 0;
112}
113
114void hns_mac_adjust_link(struct hns_mac_cb *mac_cb, int speed, int duplex)
115{
116 int ret;
117 struct mac_driver *mac_ctrl_drv;
118
119 mac_ctrl_drv = (struct mac_driver *)(mac_cb->priv.mac);
120
121 mac_cb->speed = speed;
122 mac_cb->half_duplex = !duplex;
511e6bc0 123
124 if (mac_ctrl_drv->adjust_link) {
125 ret = mac_ctrl_drv->adjust_link(mac_ctrl_drv,
126 (enum mac_speed)speed, duplex);
127 if (ret) {
128 dev_err(mac_cb->dev,
451e856e 129 "adjust_link failed, %s mac%d ret = %#x!\n",
511e6bc0 130 mac_cb->dsaf_dev->ae_dev.name,
131 mac_cb->mac_id, ret);
132 return;
133 }
134 }
135}
136
137/**
138 *hns_mac_get_inner_port_num - get mac table inner port number
139 *@mac_cb: mac device
140 *@vmid: vm id
141 *@port_num:port number
142 *
143 */
58035fd9 144int hns_mac_get_inner_port_num(struct hns_mac_cb *mac_cb, u8 vmid, u8 *port_num)
511e6bc0 145{
58035fd9
DH
146 int q_num_per_vf, vf_num_per_port;
147 int vm_queue_id;
511e6bc0 148 u8 tmp_port;
511e6bc0 149
150 if (mac_cb->dsaf_dev->dsaf_mode <= DSAF_MODE_ENABLE) {
831d828b 151 if (mac_cb->mac_id != DSAF_MAX_PORT_NUM) {
511e6bc0 152 dev_err(mac_cb->dev,
451e856e 153 "input invalid, %s mac%d vmid%d !\n",
511e6bc0 154 mac_cb->dsaf_dev->ae_dev.name,
155 mac_cb->mac_id, vmid);
156 return -EINVAL;
157 }
158 } else if (mac_cb->dsaf_dev->dsaf_mode < DSAF_MODE_MAX) {
831d828b 159 if (mac_cb->mac_id >= DSAF_MAX_PORT_NUM) {
511e6bc0 160 dev_err(mac_cb->dev,
451e856e 161 "input invalid, %s mac%d vmid%d!\n",
511e6bc0 162 mac_cb->dsaf_dev->ae_dev.name,
163 mac_cb->mac_id, vmid);
164 return -EINVAL;
165 }
166 } else {
451e856e 167 dev_err(mac_cb->dev, "dsaf mode invalid, %s mac%d!\n",
511e6bc0 168 mac_cb->dsaf_dev->ae_dev.name, mac_cb->mac_id);
169 return -EINVAL;
170 }
171
831d828b 172 if (vmid >= mac_cb->dsaf_dev->rcb_common[0]->max_vfn) {
451e856e 173 dev_err(mac_cb->dev, "input invalid, %s mac%d vmid%d !\n",
511e6bc0 174 mac_cb->dsaf_dev->ae_dev.name, mac_cb->mac_id, vmid);
175 return -EINVAL;
176 }
177
58035fd9
DH
178 q_num_per_vf = mac_cb->dsaf_dev->rcb_common[0]->max_q_per_vf;
179 vf_num_per_port = mac_cb->dsaf_dev->rcb_common[0]->max_vfn;
180
181 vm_queue_id = vmid * q_num_per_vf +
182 vf_num_per_port * q_num_per_vf * mac_cb->mac_id;
183
511e6bc0 184 switch (mac_cb->dsaf_dev->dsaf_mode) {
185 case DSAF_MODE_ENABLE_FIX:
186 tmp_port = 0;
187 break;
188 case DSAF_MODE_DISABLE_FIX:
189 tmp_port = 0;
190 break;
191 case DSAF_MODE_ENABLE_0VM:
192 case DSAF_MODE_ENABLE_8VM:
193 case DSAF_MODE_ENABLE_16VM:
194 case DSAF_MODE_ENABLE_32VM:
195 case DSAF_MODE_ENABLE_128VM:
196 case DSAF_MODE_DISABLE_2PORT_8VM:
197 case DSAF_MODE_DISABLE_2PORT_16VM:
198 case DSAF_MODE_DISABLE_2PORT_64VM:
199 case DSAF_MODE_DISABLE_6PORT_0VM:
200 case DSAF_MODE_DISABLE_6PORT_2VM:
201 case DSAF_MODE_DISABLE_6PORT_4VM:
202 case DSAF_MODE_DISABLE_6PORT_16VM:
58035fd9 203 tmp_port = vm_queue_id;
511e6bc0 204 break;
205 default:
451e856e 206 dev_err(mac_cb->dev, "dsaf mode invalid, %s mac%d!\n",
511e6bc0 207 mac_cb->dsaf_dev->ae_dev.name, mac_cb->mac_id);
208 return -EINVAL;
209 }
210 tmp_port += DSAF_BASE_INNER_PORT_NUM;
211
212 *port_num = tmp_port;
213
214 return 0;
215}
216
217/**
831d828b 218 *hns_mac_change_vf_addr - change vf mac address
511e6bc0 219 *@mac_cb: mac device
220 *@vmid: vmid
221 *@addr:mac address
222 */
223int hns_mac_change_vf_addr(struct hns_mac_cb *mac_cb,
224 u32 vmid, char *addr)
225{
226 int ret;
227 struct mac_driver *mac_ctrl_drv = hns_mac_get_drv(mac_cb);
228 struct dsaf_device *dsaf_dev = mac_cb->dsaf_dev;
229 struct dsaf_drv_mac_single_dest_entry mac_entry;
230 struct mac_entry_idx *old_entry;
231
232 old_entry = &mac_cb->addr_entry_idx[vmid];
89a44093 233 if (!HNS_DSAF_IS_DEBUG(dsaf_dev)) {
511e6bc0 234 memcpy(mac_entry.addr, addr, sizeof(mac_entry.addr));
235 mac_entry.in_vlan_id = old_entry->vlan_id;
236 mac_entry.in_port_num = mac_cb->mac_id;
237 ret = hns_mac_get_inner_port_num(mac_cb, (u8)vmid,
238 &mac_entry.port_num);
239 if (ret)
240 return ret;
241
242 if ((old_entry->valid != 0) &&
243 (memcmp(old_entry->addr,
244 addr, sizeof(mac_entry.addr)) != 0)) {
245 ret = hns_dsaf_del_mac_entry(dsaf_dev,
246 old_entry->vlan_id,
247 mac_cb->mac_id,
248 old_entry->addr);
249 if (ret)
250 return ret;
251 }
252
253 ret = hns_dsaf_set_mac_uc_entry(dsaf_dev, &mac_entry);
254 if (ret)
255 return ret;
256 }
257
258 if ((mac_ctrl_drv->set_mac_addr) && (vmid == 0))
259 mac_ctrl_drv->set_mac_addr(mac_cb->priv.mac, addr);
260
261 memcpy(old_entry->addr, addr, sizeof(old_entry->addr));
262 old_entry->valid = 1;
263 return 0;
264}
265
266int hns_mac_set_multi(struct hns_mac_cb *mac_cb,
13ac695e 267 u32 port_num, char *addr, bool enable)
511e6bc0 268{
269 int ret;
270 struct dsaf_device *dsaf_dev = mac_cb->dsaf_dev;
271 struct dsaf_drv_mac_single_dest_entry mac_entry;
272
89a44093 273 if (!HNS_DSAF_IS_DEBUG(dsaf_dev) && addr) {
511e6bc0 274 memcpy(mac_entry.addr, addr, sizeof(mac_entry.addr));
275 mac_entry.in_vlan_id = 0;/*vlan_id;*/
276 mac_entry.in_port_num = mac_cb->mac_id;
277 mac_entry.port_num = port_num;
278
13ac695e 279 if (!enable)
511e6bc0 280 ret = hns_dsaf_del_mac_mc_port(dsaf_dev, &mac_entry);
281 else
282 ret = hns_dsaf_add_mac_mc_port(dsaf_dev, &mac_entry);
283 if (ret) {
284 dev_err(dsaf_dev->dev,
451e856e 285 "set mac mc port failed, %s mac%d ret = %#x!\n",
511e6bc0 286 mac_cb->dsaf_dev->ae_dev.name,
287 mac_cb->mac_id, ret);
288 return ret;
289 }
290 }
291
292 return 0;
293}
294
295/**
296 *hns_mac_del_mac - delete mac address into dsaf table,can't delete the same
297 * address twice
298 *@net_dev: net device
299 *@vfn : vf lan
300 *@mac : mac address
301 *return status
302 */
303int hns_mac_del_mac(struct hns_mac_cb *mac_cb, u32 vfn, char *mac)
304{
305 struct mac_entry_idx *old_mac;
306 struct dsaf_device *dsaf_dev;
307 u32 ret;
308
309 dsaf_dev = mac_cb->dsaf_dev;
310
311 if (vfn < DSAF_MAX_VM_NUM) {
312 old_mac = &mac_cb->addr_entry_idx[vfn];
313 } else {
314 dev_err(mac_cb->dev,
451e856e 315 "vf queue is too large, %s mac%d queue = %#x!\n",
511e6bc0 316 mac_cb->dsaf_dev->ae_dev.name, mac_cb->mac_id, vfn);
317 return -EINVAL;
318 }
319
320 if (dsaf_dev) {
321 ret = hns_dsaf_del_mac_entry(dsaf_dev, old_mac->vlan_id,
322 mac_cb->mac_id, old_mac->addr);
323 if (ret)
324 return ret;
325
326 if (memcmp(old_mac->addr, mac, sizeof(old_mac->addr)) == 0)
327 old_mac->valid = 0;
328 }
329
330 return 0;
331}
332
333static void hns_mac_param_get(struct mac_params *param,
334 struct hns_mac_cb *mac_cb)
335{
336 param->vaddr = (void *)mac_cb->vaddr;
337 param->mac_mode = hns_get_enet_interface(mac_cb);
338 memcpy(param->addr, mac_cb->addr_entry_idx[0].addr,
339 MAC_NUM_OCTETS_PER_ADDR);
340 param->mac_id = mac_cb->mac_id;
341 param->dev = mac_cb->dev;
342}
343
344/**
345 *hns_mac_queue_config_bc_en - set broadcast rx&tx enable
346 *@mac_cb: mac device
347 *@queue: queue number
348 *@en:enable
349 *retuen 0 - success , negative --fail
350 */
351static int hns_mac_port_config_bc_en(struct hns_mac_cb *mac_cb,
13ac695e 352 u32 port_num, u16 vlan_id, bool enable)
511e6bc0 353{
354 int ret;
355 struct dsaf_device *dsaf_dev = mac_cb->dsaf_dev;
356 u8 addr[MAC_NUM_OCTETS_PER_ADDR]
357 = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
358 struct dsaf_drv_mac_single_dest_entry mac_entry;
359
360 /* directy return ok in debug network mode */
361 if (mac_cb->mac_type == HNAE_PORT_DEBUG)
362 return 0;
363
89a44093 364 if (!HNS_DSAF_IS_DEBUG(dsaf_dev)) {
511e6bc0 365 memcpy(mac_entry.addr, addr, sizeof(mac_entry.addr));
366 mac_entry.in_vlan_id = vlan_id;
367 mac_entry.in_port_num = mac_cb->mac_id;
368 mac_entry.port_num = port_num;
369
13ac695e 370 if (!enable)
511e6bc0 371 ret = hns_dsaf_del_mac_mc_port(dsaf_dev, &mac_entry);
372 else
373 ret = hns_dsaf_add_mac_mc_port(dsaf_dev, &mac_entry);
374 return ret;
375 }
376
377 return 0;
378}
379
380/**
381 *hns_mac_vm_config_bc_en - set broadcast rx&tx enable
382 *@mac_cb: mac device
383 *@vmid: vm id
384 *@en:enable
385 *retuen 0 - success , negative --fail
386 */
13ac695e 387int hns_mac_vm_config_bc_en(struct hns_mac_cb *mac_cb, u32 vmid, bool enable)
511e6bc0 388{
389 int ret;
390 struct dsaf_device *dsaf_dev = mac_cb->dsaf_dev;
391 u8 port_num;
392 u8 addr[MAC_NUM_OCTETS_PER_ADDR]
393 = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
394 struct mac_entry_idx *uc_mac_entry;
395 struct dsaf_drv_mac_single_dest_entry mac_entry;
396
397 if (mac_cb->mac_type == HNAE_PORT_DEBUG)
398 return 0;
399
400 uc_mac_entry = &mac_cb->addr_entry_idx[vmid];
401
89a44093 402 if (!HNS_DSAF_IS_DEBUG(dsaf_dev)) {
511e6bc0 403 memcpy(mac_entry.addr, addr, sizeof(mac_entry.addr));
404 mac_entry.in_vlan_id = uc_mac_entry->vlan_id;
405 mac_entry.in_port_num = mac_cb->mac_id;
406 ret = hns_mac_get_inner_port_num(mac_cb, vmid, &port_num);
407 if (ret)
408 return ret;
409 mac_entry.port_num = port_num;
410
13ac695e 411 if (!enable)
511e6bc0 412 ret = hns_dsaf_del_mac_mc_port(dsaf_dev, &mac_entry);
413 else
414 ret = hns_dsaf_add_mac_mc_port(dsaf_dev, &mac_entry);
415 return ret;
416 }
417
418 return 0;
419}
420
421void hns_mac_reset(struct hns_mac_cb *mac_cb)
422{
5ada37b5
L
423 struct mac_driver *drv = hns_mac_get_drv(mac_cb);
424 bool is_ver1 = AE_IS_VER1(mac_cb->dsaf_dev->dsaf_ver);
511e6bc0 425
426 drv->mac_init(drv);
427
428 if (drv->config_max_frame_length)
429 drv->config_max_frame_length(drv, mac_cb->max_frm);
430
431 if (drv->set_tx_auto_pause_frames)
432 drv->set_tx_auto_pause_frames(drv, mac_cb->tx_pause_frm_time);
433
434 if (drv->set_an_mode)
435 drv->set_an_mode(drv, 1);
436
437 if (drv->mac_pausefrm_cfg) {
438 if (mac_cb->mac_type == HNAE_PORT_DEBUG)
5ada37b5 439 drv->mac_pausefrm_cfg(drv, !is_ver1, !is_ver1);
511e6bc0 440 else /* mac rx must disable, dsaf pfc close instead of it*/
441 drv->mac_pausefrm_cfg(drv, 0, 1);
442 }
443}
444
445int hns_mac_set_mtu(struct hns_mac_cb *mac_cb, u32 new_mtu)
446{
447 struct mac_driver *drv = hns_mac_get_drv(mac_cb);
448 u32 buf_size = mac_cb->dsaf_dev->buf_size;
449 u32 new_frm = new_mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;
da3488bb
KY
450 u32 max_frm = AE_IS_VER1(mac_cb->dsaf_dev->dsaf_ver) ?
451 MAC_MAX_MTU : MAC_MAX_MTU_V2;
511e6bc0 452
211b1384
KY
453 if (mac_cb->mac_type == HNAE_PORT_DEBUG)
454 max_frm = MAC_MAX_MTU_DBG;
455
44770e11 456 if (new_frm > HNS_RCB_RING_MAX_BD_PER_PKT * buf_size)
511e6bc0 457 return -EINVAL;
458
459 if (!drv->config_max_frame_length)
460 return -ECHILD;
461
462 /* adjust max frame to be at least the size of a standard frame */
463 if (new_frm < (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN))
464 new_frm = (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN);
465
466 drv->config_max_frame_length(drv, new_frm);
467
468 mac_cb->max_frm = new_frm;
469
470 return 0;
471}
472
473void hns_mac_start(struct hns_mac_cb *mac_cb)
474{
475 struct mac_driver *mac_drv = hns_mac_get_drv(mac_cb);
476
477 /* for virt */
478 if (mac_drv->mac_en_flg == MAC_EN_FLAG_V) {
479 /*plus 1 when the virtual mac has been enabled */
480 mac_drv->virt_dev_num += 1;
481 return;
482 }
483
484 if (mac_drv->mac_enable) {
485 mac_drv->mac_enable(mac_cb->priv.mac, MAC_COMM_MODE_RX_AND_TX);
486 mac_drv->mac_en_flg = MAC_EN_FLAG_V;
487 }
488}
489
490void hns_mac_stop(struct hns_mac_cb *mac_cb)
491{
492 struct mac_driver *mac_ctrl_drv = hns_mac_get_drv(mac_cb);
493
494 /*modified for virtualization */
495 if (mac_ctrl_drv->virt_dev_num > 0) {
496 mac_ctrl_drv->virt_dev_num -= 1;
497 if (mac_ctrl_drv->virt_dev_num > 0)
498 return;
499 }
500
501 if (mac_ctrl_drv->mac_disable)
502 mac_ctrl_drv->mac_disable(mac_cb->priv.mac,
503 MAC_COMM_MODE_RX_AND_TX);
504
505 mac_ctrl_drv->mac_en_flg = 0;
506 mac_cb->link = 0;
a24274aa 507 mac_cb->dsaf_dev->misc_op->cpld_reset_led(mac_cb);
511e6bc0 508}
509
510/**
511 * hns_mac_get_autoneg - get auto autonegotiation
512 * @mac_cb: mac control block
513 * @enable: enable or not
514 * retuen 0 - success , negative --fail
515 */
516void hns_mac_get_autoneg(struct hns_mac_cb *mac_cb, u32 *auto_neg)
517{
518 struct mac_driver *mac_ctrl_drv = hns_mac_get_drv(mac_cb);
519
520 if (mac_ctrl_drv->autoneg_stat)
521 mac_ctrl_drv->autoneg_stat(mac_ctrl_drv, auto_neg);
522 else
523 *auto_neg = 0;
524}
525
526/**
527 * hns_mac_get_pauseparam - set rx & tx pause parameter
528 * @mac_cb: mac control block
529 * @rx_en: rx enable status
530 * @tx_en: tx enable status
531 * retuen 0 - success , negative --fail
532 */
533void hns_mac_get_pauseparam(struct hns_mac_cb *mac_cb, u32 *rx_en, u32 *tx_en)
534{
535 struct mac_driver *mac_ctrl_drv = hns_mac_get_drv(mac_cb);
536
537 if (mac_ctrl_drv->get_pause_enable) {
538 mac_ctrl_drv->get_pause_enable(mac_ctrl_drv, rx_en, tx_en);
539 } else {
540 *rx_en = 0;
541 *tx_en = 0;
542 }
511e6bc0 543}
544
545/**
546 * hns_mac_set_autoneg - set auto autonegotiation
547 * @mac_cb: mac control block
548 * @enable: enable or not
549 * retuen 0 - success , negative --fail
550 */
551int hns_mac_set_autoneg(struct hns_mac_cb *mac_cb, u8 enable)
552{
553 struct mac_driver *mac_ctrl_drv = hns_mac_get_drv(mac_cb);
554
555 if (mac_cb->phy_if == PHY_INTERFACE_MODE_XGMII && enable) {
451e856e 556 dev_err(mac_cb->dev, "enabling autoneg is not allowed!\n");
511e6bc0 557 return -ENOTSUPP;
558 }
559
560 if (mac_ctrl_drv->set_an_mode)
561 mac_ctrl_drv->set_an_mode(mac_ctrl_drv, enable);
562
563 return 0;
564}
565
566/**
567 * hns_mac_set_autoneg - set rx & tx pause parameter
568 * @mac_cb: mac control block
569 * @rx_en: rx enable or not
570 * @tx_en: tx enable or not
571 * return 0 - success , negative --fail
572 */
573int hns_mac_set_pauseparam(struct hns_mac_cb *mac_cb, u32 rx_en, u32 tx_en)
574{
575 struct mac_driver *mac_ctrl_drv = hns_mac_get_drv(mac_cb);
5ada37b5 576 bool is_ver1 = AE_IS_VER1(mac_cb->dsaf_dev->dsaf_ver);
511e6bc0 577
5ada37b5
L
578 if (mac_cb->mac_type == HNAE_PORT_DEBUG) {
579 if (is_ver1 && (tx_en || rx_en)) {
451e856e 580 dev_err(mac_cb->dev, "macv1 can't enable tx/rx_pause!\n");
511e6bc0 581 return -EINVAL;
582 }
511e6bc0 583 }
584
585 if (mac_ctrl_drv->mac_pausefrm_cfg)
586 mac_ctrl_drv->mac_pausefrm_cfg(mac_ctrl_drv, rx_en, tx_en);
587
588 return 0;
589}
590
591/**
592 * hns_mac_init_ex - mac init
593 * @mac_cb: mac control block
594 * retuen 0 - success , negative --fail
595 */
596static int hns_mac_init_ex(struct hns_mac_cb *mac_cb)
597{
598 int ret;
599 struct mac_params param;
600 struct mac_driver *drv;
601
602 hns_dsaf_fix_mac_mode(mac_cb);
603
604 memset(&param, 0, sizeof(struct mac_params));
605 hns_mac_param_get(&param, mac_cb);
606
607 if (MAC_SPEED_FROM_MODE(param.mac_mode) < MAC_SPEED_10000)
608 drv = (struct mac_driver *)hns_gmac_config(mac_cb, &param);
609 else
610 drv = (struct mac_driver *)hns_xgmac_config(mac_cb, &param);
611
612 if (!drv)
613 return -ENOMEM;
614
615 mac_cb->priv.mac = (void *)drv;
616 hns_mac_reset(mac_cb);
617
618 hns_mac_adjust_link(mac_cb, mac_cb->speed, !mac_cb->half_duplex);
619
13ac695e 620 ret = hns_mac_port_config_bc_en(mac_cb, mac_cb->mac_id, 0, true);
511e6bc0 621 if (ret)
622 goto free_mac_drv;
623
624 return 0;
625
626free_mac_drv:
627 drv->mac_free(mac_cb->priv.mac);
628 mac_cb->priv.mac = NULL;
629
630 return ret;
631}
632
1d1afa2e
KY
633static int
634hns_mac_phy_parse_addr(struct device *dev, struct fwnode_handle *fwnode)
635{
636 u32 addr;
637 int ret;
638
639 ret = fwnode_property_read_u32(fwnode, "phy-addr", &addr);
640 if (ret) {
641 dev_err(dev, "has invalid PHY address ret:%d\n", ret);
642 return ret;
643 }
644
645 if (addr >= PHY_MAX_ADDR) {
646 dev_err(dev, "PHY address %i is too large\n", addr);
647 return -EINVAL;
648 }
649
650 return addr;
651}
652
1d1afa2e
KY
653static int
654hns_mac_register_phydev(struct mii_bus *mdio, struct hns_mac_cb *mac_cb,
655 u32 addr)
656{
657 struct phy_device *phy;
658 const char *phy_type;
659 bool is_c45;
660 int rc;
661
662 rc = fwnode_property_read_string(mac_cb->fw_port,
663 "phy-mode", &phy_type);
664 if (rc < 0)
665 return rc;
666
667 if (!strcmp(phy_type, phy_modes(PHY_INTERFACE_MODE_XGMII)))
668 is_c45 = 1;
669 else if (!strcmp(phy_type, phy_modes(PHY_INTERFACE_MODE_SGMII)))
670 is_c45 = 0;
671 else
672 return -ENODATA;
673
674 phy = get_phy_device(mdio, addr, is_c45);
675 if (!phy || IS_ERR(phy))
676 return -EIO;
677
cfaace26 678 phy->irq = mdio->irq[addr];
1d1afa2e
KY
679
680 /* All data is now stored in the phy struct;
681 * register it
682 */
683 rc = phy_device_register(phy);
684 if (rc) {
685 phy_device_free(phy);
686 return -ENODEV;
687 }
688
689 mac_cb->phy_dev = phy;
690
691 dev_dbg(&mdio->dev, "registered phy at address %i\n", addr);
692
693 return 0;
694}
695
696static void hns_mac_register_phy(struct hns_mac_cb *mac_cb)
697{
698 struct acpi_reference_args args;
699 struct platform_device *pdev;
700 struct mii_bus *mii_bus;
701 int rc;
702 int addr;
703
704 /* Loop over the child nodes and register a phy_device for each one */
705 if (!to_acpi_device_node(mac_cb->fw_port))
706 return;
707
708 rc = acpi_node_get_property_reference(
709 mac_cb->fw_port, "mdio-node", 0, &args);
710 if (rc)
711 return;
712
713 addr = hns_mac_phy_parse_addr(mac_cb->dev, mac_cb->fw_port);
714 if (addr < 0)
715 return;
716
717 /* dev address in adev */
d605916b 718 pdev = hns_dsaf_find_platform_device(acpi_fwnode_handle(args.adev));
1d1afa2e
KY
719 mii_bus = platform_get_drvdata(pdev);
720 rc = hns_mac_register_phydev(mii_bus, mac_cb, addr);
721 if (!rc)
722 dev_dbg(mac_cb->dev, "mac%d register phy addr:%d\n",
723 mac_cb->mac_id, addr);
724}
725
5d2525f7
KY
726#define MAC_MEDIA_TYPE_MAX_LEN 16
727
728static const struct {
729 enum hnae_media_type value;
730 const char *name;
731} media_type_defs[] = {
732 {HNAE_MEDIA_TYPE_UNKNOWN, "unknown" },
733 {HNAE_MEDIA_TYPE_FIBER, "fiber" },
734 {HNAE_MEDIA_TYPE_COPPER, "copper" },
735 {HNAE_MEDIA_TYPE_BACKPLANE, "backplane" },
736};
737
511e6bc0 738/**
831d828b 739 *hns_mac_get_info - get mac information from device node
511e6bc0 740 *@mac_cb: mac device
741 *@np:device node
831d828b 742 * return: 0 --success, negative --fail
511e6bc0 743 */
831d828b 744static int hns_mac_get_info(struct hns_mac_cb *mac_cb)
511e6bc0 745{
652d39b0 746 struct device_node *np;
831d828b 747 struct regmap *syscon;
1ffdfac9 748 struct of_phandle_args cpld_args;
5d2525f7
KY
749 const char *media_type;
750 u32 i;
31d4446d
YZZ
751 u32 ret;
752
511e6bc0 753 mac_cb->link = false;
754 mac_cb->half_duplex = false;
5d2525f7 755 mac_cb->media_type = HNAE_MEDIA_TYPE_UNKNOWN;
511e6bc0 756 mac_cb->speed = mac_phy_to_speed[mac_cb->phy_if];
757 mac_cb->max_speed = mac_cb->speed;
758
759 if (mac_cb->phy_if == PHY_INTERFACE_MODE_SGMII) {
760 mac_cb->if_support = MAC_GMAC_SUPPORTED;
761 mac_cb->if_support |= SUPPORTED_1000baseT_Full;
762 } else if (mac_cb->phy_if == PHY_INTERFACE_MODE_XGMII) {
763 mac_cb->if_support = SUPPORTED_10000baseR_FEC;
764 mac_cb->if_support |= SUPPORTED_10000baseKR_Full;
765 }
766
767 mac_cb->max_frm = MAC_DEFAULT_MTU;
768 mac_cb->tx_pause_frm_time = MAC_DEFAULT_PAUSE_TIME;
850bfa3b 769 mac_cb->port_rst_off = mac_cb->mac_id;
0d768fc6 770 mac_cb->port_mode_off = 0;
511e6bc0 771
831d828b
YZZ
772 /* if the dsaf node doesn't contain a port subnode, get phy-handle
773 * from dsaf node
774 */
775 if (!mac_cb->fw_port) {
652d39b0
KY
776 np = of_parse_phandle(mac_cb->dev->of_node, "phy-handle",
777 mac_cb->mac_id);
778 mac_cb->phy_dev = of_phy_find_device(np);
779 if (mac_cb->phy_dev) {
780 /* refcount is held by of_phy_find_device()
781 * if the phy_dev is found
782 */
783 put_device(&mac_cb->phy_dev->mdio.dev);
784
831d828b 785 dev_dbg(mac_cb->dev, "mac%d phy_node: %s\n",
652d39b0
KY
786 mac_cb->mac_id, np->name);
787 }
b2e45406 788 of_node_put(np);
652d39b0 789
831d828b
YZZ
790 return 0;
791 }
652d39b0 792
8413b3be 793 if (is_of_node(mac_cb->fw_port)) {
1d1afa2e
KY
794 /* parse property from port subnode in dsaf */
795 np = of_parse_phandle(to_of_node(mac_cb->fw_port),
796 "phy-handle", 0);
797 mac_cb->phy_dev = of_phy_find_device(np);
798 if (mac_cb->phy_dev) {
799 /* refcount is held by of_phy_find_device()
800 * if the phy_dev is found
801 */
802 put_device(&mac_cb->phy_dev->mdio.dev);
803 dev_dbg(mac_cb->dev, "mac%d phy_node: %s\n",
804 mac_cb->mac_id, np->name);
652d39b0 805 }
b2e45406 806 of_node_put(np);
652d39b0 807
b2e45406
PC
808 np = of_parse_phandle(to_of_node(mac_cb->fw_port),
809 "serdes-syscon", 0);
810 syscon = syscon_node_to_regmap(np);
811 of_node_put(np);
8413b3be
KY
812 if (IS_ERR_OR_NULL(syscon)) {
813 dev_err(mac_cb->dev, "serdes-syscon is needed!\n");
814 return -EINVAL;
815 }
816 mac_cb->serdes_ctrl = syscon;
850bfa3b 817
8413b3be
KY
818 ret = fwnode_property_read_u32(mac_cb->fw_port,
819 "port-rst-offset",
820 &mac_cb->port_rst_off);
821 if (ret) {
822 dev_dbg(mac_cb->dev,
823 "mac%d port-rst-offset not found, use default value.\n",
824 mac_cb->mac_id);
825 }
0d768fc6 826
8413b3be
KY
827 ret = fwnode_property_read_u32(mac_cb->fw_port,
828 "port-mode-offset",
829 &mac_cb->port_mode_off);
830 if (ret) {
831 dev_dbg(mac_cb->dev,
832 "mac%d port-mode-offset not found, use default value.\n",
833 mac_cb->mac_id);
834 }
835
836 ret = of_parse_phandle_with_fixed_args(
837 to_of_node(mac_cb->fw_port), "cpld-syscon", 1, 0,
838 &cpld_args);
839 if (ret) {
840 dev_dbg(mac_cb->dev, "mac%d no cpld-syscon found.\n",
841 mac_cb->mac_id);
1ffdfac9
YZZ
842 mac_cb->cpld_ctrl = NULL;
843 } else {
8413b3be
KY
844 syscon = syscon_node_to_regmap(cpld_args.np);
845 if (IS_ERR_OR_NULL(syscon)) {
846 dev_dbg(mac_cb->dev, "no cpld-syscon found!\n");
847 mac_cb->cpld_ctrl = NULL;
848 } else {
849 mac_cb->cpld_ctrl = syscon;
850 mac_cb->cpld_ctrl_reg = cpld_args.args[0];
851 }
31d4446d 852 }
1d1afa2e
KY
853 } else if (is_acpi_node(mac_cb->fw_port)) {
854 hns_mac_register_phy(mac_cb);
855 } else {
856 dev_err(mac_cb->dev, "mac%d cannot find phy node\n",
857 mac_cb->mac_id);
31d4446d 858 }
1ffdfac9 859
5d2525f7
KY
860 if (!fwnode_property_read_string(mac_cb->fw_port, "media-type",
861 &media_type)) {
862 for (i = 0; i < ARRAY_SIZE(media_type_defs); i++) {
863 if (!strncmp(media_type_defs[i].name, media_type,
864 MAC_MEDIA_TYPE_MAX_LEN)) {
865 mac_cb->media_type = media_type_defs[i].value;
866 break;
867 }
868 }
869 }
870
831d828b 871 return 0;
511e6bc0 872}
873
874/**
875 * hns_mac_get_mode - get mac mode
876 * @phy_if: phy interface
877 * retuen 0 - gmac, 1 - xgmac , negative --fail
878 */
879static int hns_mac_get_mode(phy_interface_t phy_if)
880{
881 switch (phy_if) {
882 case PHY_INTERFACE_MODE_SGMII:
883 return MAC_GMAC_IDX;
884 case PHY_INTERFACE_MODE_XGMII:
885 return MAC_XGMAC_IDX;
886 default:
887 return -EINVAL;
888 }
889}
890
891u8 __iomem *hns_mac_get_vaddr(struct dsaf_device *dsaf_dev,
892 struct hns_mac_cb *mac_cb, u32 mac_mode_idx)
893{
894 u8 __iomem *base = dsaf_dev->io_base;
895 int mac_id = mac_cb->mac_id;
896
897 if (mac_cb->mac_type == HNAE_PORT_SERVICE)
898 return base + 0x40000 + mac_id * 0x4000 -
899 mac_mode_idx * 0x20000;
900 else
831d828b 901 return dsaf_dev->ppe_base + 0x1000;
511e6bc0 902}
903
904/**
905 * hns_mac_get_cfg - get mac cfg from dtb or acpi table
906 * @dsaf_dev: dsa fabric device struct pointer
831d828b
YZZ
907 * @mac_cb: mac control block
908 * return 0 - success , negative --fail
511e6bc0 909 */
831d828b 910int hns_mac_get_cfg(struct dsaf_device *dsaf_dev, struct hns_mac_cb *mac_cb)
511e6bc0 911{
912 int ret;
913 u32 mac_mode_idx;
511e6bc0 914
915 mac_cb->dsaf_dev = dsaf_dev;
916 mac_cb->dev = dsaf_dev->dev;
511e6bc0 917
918 mac_cb->sys_ctl_vaddr = dsaf_dev->sc_base;
919 mac_cb->serdes_vaddr = dsaf_dev->sds_base;
920
511e6bc0 921 mac_cb->sfp_prsnt = 0;
922 mac_cb->txpkt_for_led = 0;
923 mac_cb->rxpkt_for_led = 0;
924
831d828b 925 if (!HNS_DSAF_IS_DEBUG(dsaf_dev))
511e6bc0 926 mac_cb->mac_type = HNAE_PORT_SERVICE;
927 else
928 mac_cb->mac_type = HNAE_PORT_DEBUG;
929
a24274aa 930 mac_cb->phy_if = dsaf_dev->misc_op->get_phy_if(mac_cb);
511e6bc0 931
932 ret = hns_mac_get_mode(mac_cb->phy_if);
933 if (ret < 0) {
934 dev_err(dsaf_dev->dev,
451e856e 935 "hns_mac_get_mode failed, mac%d ret = %#x!\n",
511e6bc0 936 mac_cb->mac_id, ret);
937 return ret;
938 }
939 mac_mode_idx = (u32)ret;
940
831d828b
YZZ
941 ret = hns_mac_get_info(mac_cb);
942 if (ret)
943 return ret;
511e6bc0 944
a24274aa 945 mac_cb->dsaf_dev->misc_op->cpld_reset_led(mac_cb);
511e6bc0 946 mac_cb->vaddr = hns_mac_get_vaddr(dsaf_dev, mac_cb, mac_mode_idx);
947
948 return 0;
949}
950
831d828b
YZZ
951static int hns_mac_get_max_port_num(struct dsaf_device *dsaf_dev)
952{
953 if (HNS_DSAF_IS_DEBUG(dsaf_dev))
954 return 1;
955 else
956 return DSAF_MAX_PORT_NUM;
957}
958
511e6bc0 959/**
960 * hns_mac_init - init mac
961 * @dsaf_dev: dsa fabric device struct pointer
831d828b 962 * return 0 - success , negative --fail
511e6bc0 963 */
964int hns_mac_init(struct dsaf_device *dsaf_dev)
965{
831d828b 966 bool found = false;
511e6bc0 967 int ret;
831d828b
YZZ
968 u32 port_id;
969 int max_port_num = hns_mac_get_max_port_num(dsaf_dev);
511e6bc0 970 struct hns_mac_cb *mac_cb;
831d828b 971 struct fwnode_handle *child;
511e6bc0 972
831d828b 973 device_for_each_child_node(dsaf_dev->dev, child) {
0211b8fb 974 ret = fwnode_property_read_u32(child, "reg", &port_id);
831d828b
YZZ
975 if (ret) {
976 dev_err(dsaf_dev->dev,
0211b8fb 977 "get reg fail, ret=%d!\n", ret);
831d828b
YZZ
978 return ret;
979 }
980 if (port_id >= max_port_num) {
981 dev_err(dsaf_dev->dev,
0211b8fb 982 "reg(%u) out of range!\n", port_id);
831d828b
YZZ
983 return -EINVAL;
984 }
985 mac_cb = devm_kzalloc(dsaf_dev->dev, sizeof(*mac_cb),
986 GFP_KERNEL);
987 if (!mac_cb)
988 return -ENOMEM;
989 mac_cb->fw_port = child;
990 mac_cb->mac_id = (u8)port_id;
991 dsaf_dev->mac_cb[port_id] = mac_cb;
992 found = true;
993 }
511e6bc0 994
831d828b
YZZ
995 /* if don't get any port subnode from dsaf node
996 * will init all port then, this is compatible with the old dts
997 */
998 if (!found) {
999 for (port_id = 0; port_id < max_port_num; port_id++) {
1000 mac_cb = devm_kzalloc(dsaf_dev->dev, sizeof(*mac_cb),
1001 GFP_KERNEL);
1002 if (!mac_cb)
1003 return -ENOMEM;
1004
1005 mac_cb->mac_id = port_id;
1006 dsaf_dev->mac_cb[port_id] = mac_cb;
1007 }
1008 }
1009 /* init mac_cb for all port */
1010 for (port_id = 0; port_id < max_port_num; port_id++) {
1011 mac_cb = dsaf_dev->mac_cb[port_id];
1012 if (!mac_cb)
1013 continue;
511e6bc0 1014
831d828b
YZZ
1015 ret = hns_mac_get_cfg(dsaf_dev, mac_cb);
1016 if (ret)
1017 return ret;
511e6bc0 1018 ret = hns_mac_init_ex(mac_cb);
1019 if (ret)
831d828b 1020 return ret;
511e6bc0 1021 }
1022
1023 return 0;
511e6bc0 1024}
1025
1026void hns_mac_uninit(struct dsaf_device *dsaf_dev)
1027{
831d828b
YZZ
1028 int i;
1029 int max_port_num = hns_mac_get_max_port_num(dsaf_dev);
1030
1031 for (i = 0; i < max_port_num; i++) {
a24274aa 1032 dsaf_dev->misc_op->cpld_reset_led(dsaf_dev->mac_cb[i]);
831d828b
YZZ
1033 dsaf_dev->mac_cb[i] = NULL;
1034 }
511e6bc0 1035}
1036
1037int hns_mac_config_mac_loopback(struct hns_mac_cb *mac_cb,
1038 enum hnae_loop loop, int en)
1039{
1040 int ret;
1041 struct mac_driver *drv = hns_mac_get_drv(mac_cb);
1042
1043 if (drv->config_loopback)
1044 ret = drv->config_loopback(drv, loop, en);
1045 else
1046 ret = -ENOTSUPP;
1047
1048 return ret;
1049}
1050
1051void hns_mac_update_stats(struct hns_mac_cb *mac_cb)
1052{
1053 struct mac_driver *mac_ctrl_drv = hns_mac_get_drv(mac_cb);
1054
1055 mac_ctrl_drv->update_stats(mac_ctrl_drv);
1056}
1057
1058void hns_mac_get_stats(struct hns_mac_cb *mac_cb, u64 *data)
1059{
1060 struct mac_driver *mac_ctrl_drv = hns_mac_get_drv(mac_cb);
1061
1062 mac_ctrl_drv->get_ethtool_stats(mac_ctrl_drv, data);
1063}
1064
1065void hns_mac_get_strings(struct hns_mac_cb *mac_cb,
1066 int stringset, u8 *data)
1067{
1068 struct mac_driver *mac_ctrl_drv = hns_mac_get_drv(mac_cb);
1069
1070 mac_ctrl_drv->get_strings(stringset, data);
1071}
1072
1073int hns_mac_get_sset_count(struct hns_mac_cb *mac_cb, int stringset)
1074{
1075 struct mac_driver *mac_ctrl_drv = hns_mac_get_drv(mac_cb);
1076
1077 return mac_ctrl_drv->get_sset_count(stringset);
1078}
1079
d5679849
KY
1080void hns_mac_set_promisc(struct hns_mac_cb *mac_cb, u8 en)
1081{
1082 struct mac_driver *mac_ctrl_drv = hns_mac_get_drv(mac_cb);
1083
1084 if (mac_ctrl_drv->set_promiscuous)
1085 mac_ctrl_drv->set_promiscuous(mac_ctrl_drv, en);
1086}
1087
511e6bc0 1088int hns_mac_get_regs_count(struct hns_mac_cb *mac_cb)
1089{
1090 struct mac_driver *mac_ctrl_drv = hns_mac_get_drv(mac_cb);
1091
1092 return mac_ctrl_drv->get_regs_count();
1093}
1094
1095void hns_mac_get_regs(struct hns_mac_cb *mac_cb, void *data)
1096{
1097 struct mac_driver *mac_ctrl_drv = hns_mac_get_drv(mac_cb);
1098
1099 mac_ctrl_drv->get_regs(mac_ctrl_drv, data);
1100}
1101
1102void hns_set_led_opt(struct hns_mac_cb *mac_cb)
1103{
1104 int nic_data = 0;
1105 int txpkts, rxpkts;
1106
1107 txpkts = mac_cb->txpkt_for_led - mac_cb->hw_stats.tx_good_pkts;
1108 rxpkts = mac_cb->rxpkt_for_led - mac_cb->hw_stats.rx_good_pkts;
1109 if (txpkts || rxpkts)
1110 nic_data = 1;
1111 else
1112 nic_data = 0;
1113 mac_cb->txpkt_for_led = mac_cb->hw_stats.tx_good_pkts;
1114 mac_cb->rxpkt_for_led = mac_cb->hw_stats.rx_good_pkts;
a24274aa 1115 mac_cb->dsaf_dev->misc_op->cpld_set_led(mac_cb, (int)mac_cb->link,
511e6bc0 1116 mac_cb->speed, nic_data);
1117}
1118
1119int hns_cpld_led_set_id(struct hns_mac_cb *mac_cb,
1120 enum hnae_led_state status)
1121{
31d4446d 1122 if (!mac_cb || !mac_cb->cpld_ctrl)
511e6bc0 1123 return 0;
1124
a24274aa 1125 return mac_cb->dsaf_dev->misc_op->cpld_set_led_id(mac_cb, status);
511e6bc0 1126}