From d52f17ee67b60e22251399fd230000e1a1cb2ca9 Mon Sep 17 00:00:00 2001 From: davidcs Date: Mon, 17 Oct 2016 18:14:31 +0000 Subject: [PATCH] MFC r306790 Add support for adding up to 64 Multicast addresses with a single mailbox command git-svn-id: svn://svn.freebsd.org/base/stable/9@307526 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- sys/dev/qlxgbe/ql_hw.c | 214 +++++++++++++++++++++++++++++----------- sys/dev/qlxgbe/ql_hw.h | 8 +- sys/dev/qlxgbe/ql_os.c | 8 +- sys/dev/qlxgbe/ql_ver.h | 2 +- 4 files changed, 169 insertions(+), 63 deletions(-) diff --git a/sys/dev/qlxgbe/ql_hw.c b/sys/dev/qlxgbe/ql_hw.c index ad8dba5f8..8c40aba98 100644 --- a/sys/dev/qlxgbe/ql_hw.c +++ b/sys/dev/qlxgbe/ql_hw.c @@ -1128,12 +1128,21 @@ qla_config_intr_coalesce(qla_host_t *ha, uint16_t cntxt_id, int tenable, * Can be unicast, multicast or broadcast. */ static int -qla_config_mac_addr(qla_host_t *ha, uint8_t *mac_addr, uint32_t add_mac) +qla_config_mac_addr(qla_host_t *ha, uint8_t *mac_addr, uint32_t add_mac, + uint32_t num_mac) { q80_config_mac_addr_t *cmac; q80_config_mac_addr_rsp_t *cmac_rsp; uint32_t err; device_t dev = ha->pci_dev; + int i; + uint8_t *mac_cpy = mac_addr; + + if (num_mac > Q8_MAX_MAC_ADDRS) { + device_printf(dev, "%s: %s num_mac [0x%x] > Q8_MAX_MAC_ADDRS\n", + __func__, (add_mac ? "Add" : "Del"), num_mac); + return (-1); + } cmac = (q80_config_mac_addr_t *)ha->hw.mbox; bzero(cmac, (sizeof (q80_config_mac_addr_t))); @@ -1149,9 +1158,13 @@ qla_config_mac_addr(qla_host_t *ha, uint8_t *mac_addr, uint32_t add_mac) cmac->cmd |= Q8_MBX_CMAC_CMD_CAM_INGRESS; - cmac->nmac_entries = 1; + cmac->nmac_entries = num_mac; cmac->cntxt_id = ha->hw.rcv_cntxt_id; - bcopy(mac_addr, cmac->mac_addr[0].addr, 6); + + for (i = 0; i < num_mac; i++) { + bcopy(mac_addr, cmac->mac_addr[i].addr, Q8_ETHER_ADDR_LEN); + mac_addr = mac_addr + ETHER_ADDR_LEN; + } if (qla_mbx_cmd(ha, (uint32_t *)cmac, (sizeof (q80_config_mac_addr_t) >> 2), @@ -1165,11 +1178,14 @@ qla_config_mac_addr(qla_host_t *ha, uint8_t *mac_addr, uint32_t add_mac) err = Q8_MBX_RSP_STATUS(cmac_rsp->regcnt_status); if (err) { - device_printf(dev, "%s: %s " - "%02x:%02x:%02x:%02x:%02x:%02x failed1 [0x%08x]\n", - __func__, (add_mac ? "Add" : "Del"), - mac_addr[0], mac_addr[1], mac_addr[2], - mac_addr[3], mac_addr[4], mac_addr[5], err); + device_printf(dev, "%s: %s failed1 [0x%08x]\n", __func__, + (add_mac ? "Add" : "Del"), err); + for (i = 0; i < num_mac; i++) { + device_printf(dev, "%s: %02x:%02x:%02x:%02x:%02x:%02x\n", + __func__, mac_cpy[0], mac_cpy[1], mac_cpy[2], + mac_cpy[3], mac_cpy[4], mac_cpy[5]); + mac_cpy += ETHER_ADDR_LEN; + } return (-1); } @@ -2254,6 +2270,7 @@ ql_del_hw_if(qla_host_t *ha) (void)qla_stop_nic_func(ha); qla_del_rcv_cntxt(ha); + qla_del_xmt_cntxt(ha); if (ha->hw.flags.init_intr_cnxt) { @@ -2270,6 +2287,7 @@ ql_del_hw_if(qla_host_t *ha) ha->hw.flags.init_intr_cnxt = 0; } + return; } @@ -2368,7 +2386,7 @@ ql_init_hw_if(qla_host_t *ha) } ha->hw.max_tx_segs = 0; - if (qla_config_mac_addr(ha, ha->hw.mac_addr, 1)) + if (qla_config_mac_addr(ha, ha->hw.mac_addr, 1, 1)) return(-1); ha->hw.flags.unicast_mac = 1; @@ -2376,7 +2394,7 @@ ql_init_hw_if(qla_host_t *ha) bcast_mac[0] = 0xFF; bcast_mac[1] = 0xFF; bcast_mac[2] = 0xFF; bcast_mac[3] = 0xFF; bcast_mac[4] = 0xFF; bcast_mac[5] = 0xFF; - if (qla_config_mac_addr(ha, bcast_mac, 1)) + if (qla_config_mac_addr(ha, bcast_mac, 1, 1)) return (-1); ha->hw.flags.bcast_mac = 1; @@ -2733,14 +2751,14 @@ qla_del_rcv_cntxt(qla_host_t *ha) bcast_mac[0] = 0xFF; bcast_mac[1] = 0xFF; bcast_mac[2] = 0xFF; bcast_mac[3] = 0xFF; bcast_mac[4] = 0xFF; bcast_mac[5] = 0xFF; - if (qla_config_mac_addr(ha, bcast_mac, 0)) + if (qla_config_mac_addr(ha, bcast_mac, 0, 1)) return; ha->hw.flags.bcast_mac = 0; } if (ha->hw.flags.unicast_mac) { - if (qla_config_mac_addr(ha, ha->hw.mac_addr, 0)) + if (qla_config_mac_addr(ha, ha->hw.mac_addr, 0, 1)) return; ha->hw.flags.unicast_mac = 0; } @@ -2926,12 +2944,20 @@ qla_init_xmt_cntxt(qla_host_t *ha) } static int -qla_hw_add_all_mcast(qla_host_t *ha) +qla_hw_all_mcast(qla_host_t *ha, uint32_t add_mcast) { int i, nmcast; + uint32_t count = 0; + uint8_t *mcast; nmcast = ha->hw.nmcast; + QL_DPRINT2(ha, (ha->pci_dev, + "%s:[0x%x] enter nmcast = %d \n", __func__, add_mcast, nmcast)); + + mcast = ha->hw.mac_addr_arr; + memset(mcast, 0, (Q8_MAX_MAC_ADDRS * ETHER_ADDR_LEN)); + for (i = 0 ; ((i < Q8_MAX_NUM_MULTICAST_ADDRS) && nmcast); i++) { if ((ha->hw.mcast[i].addr[0] != 0) || (ha->hw.mcast[i].addr[1] != 0) || @@ -2940,52 +2966,80 @@ qla_hw_add_all_mcast(qla_host_t *ha) (ha->hw.mcast[i].addr[4] != 0) || (ha->hw.mcast[i].addr[5] != 0)) { - if (qla_config_mac_addr(ha, ha->hw.mcast[i].addr, 1)) { - device_printf(ha->pci_dev, "%s: failed\n", - __func__); - return (-1); + bcopy(ha->hw.mcast[i].addr, mcast, ETHER_ADDR_LEN); + mcast = mcast + ETHER_ADDR_LEN; + count++; + + if (count == Q8_MAX_MAC_ADDRS) { + if (qla_config_mac_addr(ha, ha->hw.mac_addr_arr, + add_mcast, count)) { + device_printf(ha->pci_dev, + "%s: failed\n", __func__); + return (-1); + } + + count = 0; + mcast = ha->hw.mac_addr_arr; + memset(mcast, 0, + (Q8_MAX_MAC_ADDRS * ETHER_ADDR_LEN)); } nmcast--; } } + + if (count) { + if (qla_config_mac_addr(ha, ha->hw.mac_addr_arr, add_mcast, + count)) { + device_printf(ha->pci_dev, "%s: failed\n", __func__); + return (-1); + } + } + QL_DPRINT2(ha, (ha->pci_dev, + "%s:[0x%x] exit nmcast = %d \n", __func__, add_mcast, nmcast)); + return 0; } static int -qla_hw_del_all_mcast(qla_host_t *ha) +qla_hw_add_all_mcast(qla_host_t *ha) { - int i, nmcast; + int ret; - nmcast = ha->hw.nmcast; + ret = qla_hw_all_mcast(ha, 1); - for (i = 0 ; ((i < Q8_MAX_NUM_MULTICAST_ADDRS) && nmcast); i++) { - if ((ha->hw.mcast[i].addr[0] != 0) || - (ha->hw.mcast[i].addr[1] != 0) || - (ha->hw.mcast[i].addr[2] != 0) || - (ha->hw.mcast[i].addr[3] != 0) || - (ha->hw.mcast[i].addr[4] != 0) || - (ha->hw.mcast[i].addr[5] != 0)) { + return (ret); +} - if (qla_config_mac_addr(ha, ha->hw.mcast[i].addr, 0)) - return (-1); +static int +qla_hw_del_all_mcast(qla_host_t *ha) +{ + int ret; - nmcast--; - } - } - return 0; + ret = qla_hw_all_mcast(ha, 0); + + bzero(ha->hw.mcast, (sizeof (qla_mcast_t) * Q8_MAX_NUM_MULTICAST_ADDRS)); + ha->hw.nmcast = 0; + + return (ret); } static int -qla_hw_add_mcast(qla_host_t *ha, uint8_t *mta) +qla_hw_mac_addr_present(qla_host_t *ha, uint8_t *mta) { int i; for (i = 0; i < Q8_MAX_NUM_MULTICAST_ADDRS; i++) { - if (QL_MAC_CMP(ha->hw.mcast[i].addr, mta) == 0) - return 0; /* its been already added */ + return (0); /* its been already added */ } + return (-1); +} + +static int +qla_hw_add_mcast(qla_host_t *ha, uint8_t *mta, uint32_t nmcast) +{ + int i; for (i = 0; i < Q8_MAX_NUM_MULTICAST_ADDRS; i++) { @@ -2996,29 +3050,28 @@ qla_hw_add_mcast(qla_host_t *ha, uint8_t *mta) (ha->hw.mcast[i].addr[4] == 0) && (ha->hw.mcast[i].addr[5] == 0)) { - if (qla_config_mac_addr(ha, mta, 1)) - return (-1); - bcopy(mta, ha->hw.mcast[i].addr, Q8_MAC_ADDR_LEN); ha->hw.nmcast++; - return 0; + mta = mta + ETHER_ADDR_LEN; + nmcast--; + + if (nmcast == 0) + break; } + } return 0; } static int -qla_hw_del_mcast(qla_host_t *ha, uint8_t *mta) +qla_hw_del_mcast(qla_host_t *ha, uint8_t *mta, uint32_t nmcast) { int i; for (i = 0; i < Q8_MAX_NUM_MULTICAST_ADDRS; i++) { if (QL_MAC_CMP(ha->hw.mcast[i].addr, mta) == 0) { - if (qla_config_mac_addr(ha, mta, 0)) - return (-1); - ha->hw.mcast[i].addr[0] = 0; ha->hw.mcast[i].addr[1] = 0; ha->hw.mcast[i].addr[2] = 0; @@ -3028,7 +3081,11 @@ qla_hw_del_mcast(qla_host_t *ha, uint8_t *mta) ha->hw.nmcast--; - return 0; + mta = mta + ETHER_ADDR_LEN; + nmcast--; + + if (nmcast == 0) + break; } } return 0; @@ -3036,30 +3093,75 @@ qla_hw_del_mcast(qla_host_t *ha, uint8_t *mta) /* * Name: ql_hw_set_multi - * Function: Sets the Multicast Addresses provided the host O.S into the + * Function: Sets the Multicast Addresses provided by the host O.S into the * hardware (for the given interface) */ int -ql_hw_set_multi(qla_host_t *ha, uint8_t *mcast, uint32_t mcnt, +ql_hw_set_multi(qla_host_t *ha, uint8_t *mcast_addr, uint32_t mcnt, uint32_t add_mac) { + uint8_t *mta = mcast_addr; int i; - uint8_t *mta = mcast; int ret = 0; + uint32_t count = 0; + uint8_t *mcast; + + mcast = ha->hw.mac_addr_arr; + memset(mcast, 0, (Q8_MAX_MAC_ADDRS * ETHER_ADDR_LEN)); for (i = 0; i < mcnt; i++) { - if (add_mac) { - ret = qla_hw_add_mcast(ha, mta); - if (ret) - break; - } else { - ret = qla_hw_del_mcast(ha, mta); - if (ret) - break; + if (mta[0] || mta[1] || mta[2] || mta[3] || mta[4] || mta[5]) { + if (add_mac) { + if (qla_hw_mac_addr_present(ha, mta) != 0) { + bcopy(mta, mcast, ETHER_ADDR_LEN); + mcast = mcast + ETHER_ADDR_LEN; + count++; + } + } else { + if (qla_hw_mac_addr_present(ha, mta) == 0) { + bcopy(mta, mcast, ETHER_ADDR_LEN); + mcast = mcast + ETHER_ADDR_LEN; + count++; + } + } + } + if (count == Q8_MAX_MAC_ADDRS) { + if (qla_config_mac_addr(ha, ha->hw.mac_addr_arr, + add_mac, count)) { + device_printf(ha->pci_dev, "%s: failed\n", + __func__); + return (-1); + } + + if (add_mac) { + qla_hw_add_mcast(ha, ha->hw.mac_addr_arr, + count); + } else { + qla_hw_del_mcast(ha, ha->hw.mac_addr_arr, + count); + } + + count = 0; + mcast = ha->hw.mac_addr_arr; + memset(mcast, 0, (Q8_MAX_MAC_ADDRS * ETHER_ADDR_LEN)); } mta += Q8_MAC_ADDR_LEN; } + + if (count) { + if (qla_config_mac_addr(ha, ha->hw.mac_addr_arr, add_mac, + count)) { + device_printf(ha->pci_dev, "%s: failed\n", __func__); + return (-1); + } + if (add_mac) { + qla_hw_add_mcast(ha, ha->hw.mac_addr_arr, count); + } else { + qla_hw_del_mcast(ha, ha->hw.mac_addr_arr, count); + } + } + return (ret); } diff --git a/sys/dev/qlxgbe/ql_hw.h b/sys/dev/qlxgbe/ql_hw.h index ff3321982..e50bc5edb 100644 --- a/sys/dev/qlxgbe/ql_hw.h +++ b/sys/dev/qlxgbe/ql_hw.h @@ -210,7 +210,7 @@ #define Q8_NUM_MBOX 512 -#define Q8_MAX_NUM_MULTICAST_ADDRS 1023 +#define Q8_MAX_NUM_MULTICAST_ADDRS 1022 #define Q8_MAC_ADDR_LEN 6 /* @@ -511,8 +511,9 @@ typedef struct _q80_config_intr_coalesc_rsp { /* * Configure MAC Address */ +#define Q8_ETHER_ADDR_LEN 6 typedef struct _q80_mac_addr { - uint8_t addr[6]; + uint8_t addr[Q8_ETHER_ADDR_LEN]; uint16_t vlan_tci; } __packed q80_mac_addr_t; @@ -1548,7 +1549,7 @@ typedef struct _qla_hw_tx_cntxt { typedef struct _qla_mcast { uint16_t rsrvd; - uint8_t addr[6]; + uint8_t addr[ETHER_ADDR_LEN]; } __packed qla_mcast_t; typedef struct _qla_rdesc { @@ -1660,6 +1661,7 @@ typedef struct _qla_hw { /* multicast address list */ uint32_t nmcast; qla_mcast_t mcast[Q8_MAX_NUM_MULTICAST_ADDRS]; + uint8_t mac_addr_arr[(Q8_MAX_MAC_ADDRS * ETHER_ADDR_LEN)]; /* reset sequence */ #define Q8_MAX_RESET_SEQ_IDX 16 diff --git a/sys/dev/qlxgbe/ql_os.c b/sys/dev/qlxgbe/ql_os.c index 14b6e6d1b..1ecf80e8b 100644 --- a/sys/dev/qlxgbe/ql_os.c +++ b/sys/dev/qlxgbe/ql_os.c @@ -243,6 +243,8 @@ qla_watchdog(void *arg) ha->flags.qla_watchdog_pause = 1; ha->qla_initiate_recovery = 0; ha->err_inject = 0; + device_printf(ha->pci_dev, + "%s: taskqueue_enqueue(err_task) \n", __func__); taskqueue_enqueue(ha->err_tq, &ha->err_task); } else if (ha->flags.qla_interface_up) { @@ -452,7 +454,7 @@ qla_pci_attach(device_t dev) TASK_INIT(&ha->tx_task, 0, qla_tx_done, ha); - ha->tx_tq = taskqueue_create_fast("qla_txq", M_NOWAIT, + ha->tx_tq = taskqueue_create("qla_txq", M_NOWAIT, taskqueue_thread_enqueue, &ha->tx_tq); taskqueue_start_threads(&ha->tx_tq, 1, PI_NET, "%s txq", device_get_nameunit(ha->pci_dev)); @@ -470,13 +472,13 @@ qla_pci_attach(device_t dev) qla_watchdog, ha); TASK_INIT(&ha->err_task, 0, qla_error_recovery, ha); - ha->err_tq = taskqueue_create_fast("qla_errq", M_NOWAIT, + ha->err_tq = taskqueue_create("qla_errq", M_NOWAIT, taskqueue_thread_enqueue, &ha->err_tq); taskqueue_start_threads(&ha->err_tq, 1, PI_NET, "%s errq", device_get_nameunit(ha->pci_dev)); TASK_INIT(&ha->async_event_task, 0, qla_async_event, ha); - ha->async_event_tq = taskqueue_create_fast("qla_asyncq", M_NOWAIT, + ha->async_event_tq = taskqueue_create("qla_asyncq", M_NOWAIT, taskqueue_thread_enqueue, &ha->async_event_tq); taskqueue_start_threads(&ha->async_event_tq, 1, PI_NET, "%s asyncq", device_get_nameunit(ha->pci_dev)); diff --git a/sys/dev/qlxgbe/ql_ver.h b/sys/dev/qlxgbe/ql_ver.h index de8517389..182fa32c3 100644 --- a/sys/dev/qlxgbe/ql_ver.h +++ b/sys/dev/qlxgbe/ql_ver.h @@ -36,6 +36,6 @@ #define QLA_VERSION_MAJOR 3 #define QLA_VERSION_MINOR 10 -#define QLA_VERSION_BUILD 30 +#define QLA_VERSION_BUILD 31 #endif /* #ifndef _QL_VER_H_ */ -- 2.45.0