aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/cxgb4vf/t4vf_hw.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/cxgb4vf/t4vf_hw.c')
-rw-r--r--drivers/net/cxgb4vf/t4vf_hw.c113
1 files changed, 78 insertions, 35 deletions
diff --git a/drivers/net/cxgb4vf/t4vf_hw.c b/drivers/net/cxgb4vf/t4vf_hw.c
index ea1c123f0cb4..19520afe1a12 100644
--- a/drivers/net/cxgb4vf/t4vf_hw.c
+++ b/drivers/net/cxgb4vf/t4vf_hw.c
@@ -326,6 +326,25 @@ int __devinit t4vf_port_init(struct adapter *adapter, int pidx)
326} 326}
327 327
328/** 328/**
329 * t4vf_fw_reset - issue a reset to FW
330 * @adapter: the adapter
331 *
332 * Issues a reset command to FW. For a Physical Function this would
333 * result in the Firmware reseting all of its state. For a Virtual
334 * Function this just resets the state associated with the VF.
335 */
336int t4vf_fw_reset(struct adapter *adapter)
337{
338 struct fw_reset_cmd cmd;
339
340 memset(&cmd, 0, sizeof(cmd));
341 cmd.op_to_write = cpu_to_be32(FW_CMD_OP(FW_RESET_CMD) |
342 FW_CMD_WRITE);
343 cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd));
344 return t4vf_wr_mbox(adapter, &cmd, sizeof(cmd), NULL);
345}
346
347/**
329 * t4vf_query_params - query FW or device parameters 348 * t4vf_query_params - query FW or device parameters
330 * @adapter: the adapter 349 * @adapter: the adapter
331 * @nparams: the number of parameters 350 * @nparams: the number of parameters
@@ -995,48 +1014,72 @@ int t4vf_alloc_mac_filt(struct adapter *adapter, unsigned int viid, bool free,
995 unsigned int naddr, const u8 **addr, u16 *idx, 1014 unsigned int naddr, const u8 **addr, u16 *idx,
996 u64 *hash, bool sleep_ok) 1015 u64 *hash, bool sleep_ok)
997{ 1016{
998 int i, ret; 1017 int offset, ret = 0;
1018 unsigned nfilters = 0;
1019 unsigned int rem = naddr;
999 struct fw_vi_mac_cmd cmd, rpl; 1020 struct fw_vi_mac_cmd cmd, rpl;
1000 struct fw_vi_mac_exact *p;
1001 size_t len16;
1002 1021
1003 if (naddr > ARRAY_SIZE(cmd.u.exact)) 1022 if (naddr > FW_CLS_TCAM_NUM_ENTRIES)
1004 return -EINVAL; 1023 return -EINVAL;
1005 len16 = DIV_ROUND_UP(offsetof(struct fw_vi_mac_cmd,
1006 u.exact[naddr]), 16);
1007 1024
1008 memset(&cmd, 0, sizeof(cmd)); 1025 for (offset = 0; offset < naddr; /**/) {
1009 cmd.op_to_viid = cpu_to_be32(FW_CMD_OP(FW_VI_MAC_CMD) | 1026 unsigned int fw_naddr = (rem < ARRAY_SIZE(cmd.u.exact)
1010 FW_CMD_REQUEST | 1027 ? rem
1011 FW_CMD_WRITE | 1028 : ARRAY_SIZE(cmd.u.exact));
1012 (free ? FW_CMD_EXEC : 0) | 1029 size_t len16 = DIV_ROUND_UP(offsetof(struct fw_vi_mac_cmd,
1013 FW_VI_MAC_CMD_VIID(viid)); 1030 u.exact[fw_naddr]), 16);
1014 cmd.freemacs_to_len16 = cpu_to_be32(FW_VI_MAC_CMD_FREEMACS(free) | 1031 struct fw_vi_mac_exact *p;
1015 FW_CMD_LEN16(len16)); 1032 int i;
1033
1034 memset(&cmd, 0, sizeof(cmd));
1035 cmd.op_to_viid = cpu_to_be32(FW_CMD_OP(FW_VI_MAC_CMD) |
1036 FW_CMD_REQUEST |
1037 FW_CMD_WRITE |
1038 (free ? FW_CMD_EXEC : 0) |
1039 FW_VI_MAC_CMD_VIID(viid));
1040 cmd.freemacs_to_len16 =
1041 cpu_to_be32(FW_VI_MAC_CMD_FREEMACS(free) |
1042 FW_CMD_LEN16(len16));
1043
1044 for (i = 0, p = cmd.u.exact; i < fw_naddr; i++, p++) {
1045 p->valid_to_idx = cpu_to_be16(
1046 FW_VI_MAC_CMD_VALID |
1047 FW_VI_MAC_CMD_IDX(FW_VI_MAC_ADD_MAC));
1048 memcpy(p->macaddr, addr[offset+i], sizeof(p->macaddr));
1049 }
1016 1050
1017 for (i = 0, p = cmd.u.exact; i < naddr; i++, p++) {
1018 p->valid_to_idx =
1019 cpu_to_be16(FW_VI_MAC_CMD_VALID |
1020 FW_VI_MAC_CMD_IDX(FW_VI_MAC_ADD_MAC));
1021 memcpy(p->macaddr, addr[i], sizeof(p->macaddr));
1022 }
1023 1051
1024 ret = t4vf_wr_mbox_core(adapter, &cmd, sizeof(cmd), &rpl, sleep_ok); 1052 ret = t4vf_wr_mbox_core(adapter, &cmd, sizeof(cmd), &rpl,
1025 if (ret) 1053 sleep_ok);
1026 return ret; 1054 if (ret && ret != -ENOMEM)
1027 1055 break;
1028 for (i = 0, p = rpl.u.exact; i < naddr; i++, p++) { 1056
1029 u16 index = FW_VI_MAC_CMD_IDX_GET(be16_to_cpu(p->valid_to_idx)); 1057 for (i = 0, p = rpl.u.exact; i < fw_naddr; i++, p++) {
1030 1058 u16 index = FW_VI_MAC_CMD_IDX_GET(
1031 if (idx) 1059 be16_to_cpu(p->valid_to_idx));
1032 idx[i] = (index >= FW_CLS_TCAM_NUM_ENTRIES 1060
1033 ? 0xffff 1061 if (idx)
1034 : index); 1062 idx[offset+i] =
1035 if (index < FW_CLS_TCAM_NUM_ENTRIES) 1063 (index >= FW_CLS_TCAM_NUM_ENTRIES
1036 ret++; 1064 ? 0xffff
1037 else if (hash) 1065 : index);
1038 *hash |= (1 << hash_mac_addr(addr[i])); 1066 if (index < FW_CLS_TCAM_NUM_ENTRIES)
1067 nfilters++;
1068 else if (hash)
1069 *hash |= (1ULL << hash_mac_addr(addr[offset+i]));
1070 }
1071
1072 free = false;
1073 offset += fw_naddr;
1074 rem -= fw_naddr;
1039 } 1075 }
1076
1077 /*
1078 * If there were no errors or we merely ran out of room in our MAC
1079 * address arena, return the number of filters actually written.
1080 */
1081 if (ret == 0 || ret == -ENOMEM)
1082 ret = nfilters;
1040 return ret; 1083 return ret;
1041} 1084}
1042 1085